\documentclass[11pt, oneside]{article} \usepackage[ left=2cm, right=2cm, top=2cm, bottom=2cm, ]{geometry} \geometry{a4paper} \usepackage{graphicx} %% for pictures \usepackage{float} \usepackage{amssymb} %% math symbols \usepackage{amsmath} %% math matrix etc \usepackage{listings} %% code block \lstset{ language=C, showspaces=false, basicstyle=\small\ttfamily, numbers=left, numberstyle=\tiny, breaklines=true, postbreak=\mbox{\textcolor{red}{$\hookrightarrow$}\space}, backgroundcolor = \color{lightgray}, } \usepackage{enumitem} %% for lists and enumerating \usepackage{color} \usepackage{xcolor,colortbl} % xcolor for defining colors, colortbl for table colors \usepackage{makecell} %% for multiple lines in cell of table \usepackage{hyperref} %% links for table of contents \usepackage{pgfplots} %% plots used with \begin{tikzpicture} \usepackage{tikz} %% for pictures \usetikzlibrary{trees} \pgfplotsset{width=10cm,compat=newest} \usepackage{cancel} %% set max table of contents recursion to subsection (3->subsubsecition) \setcounter{tocdepth}{2} \setcounter{secnumdepth}{2} %% \definecolor{red}{rgb}{1, 0.1, 0.1} \definecolor{lightgreen}{rgb}{0.55, 0.87, 0.47} \definecolor{gray}{rgb}{0.3, 0.3, 0.3} \newcommand{\lgt}{\cellcolor{lightgreen}} %% light green in tables \newcommand{\gry}{\textcolor{gray}} %% gray text %% use bar instead of arrow for vectors \renewcommand{\vec}[1]{\bar{#1}} %% itemize use less vertical space (use olditemize for default behaviour) \let\olditemize=\itemize \let\endolditemize=\enditemize \renewenvironment{itemize}{\olditemize \itemsep-0.2em}{\endolditemize} %% items in itemize emph+box %% usage: \ieb{Class:} for simple item %% \ieb[4cm]{Class:} for specific size of box \newcommand{\ieb}[2][2cm]{ \makebox[#1][l]{\emph{#2}} } %% TODO: replace with description environment (? maybe) %---------------------------------% \title{Progetto di Laboratorio di Sistemi Operativi} \author{ Elvis Rossi - Matricola 561394 } \date{May 20, 2022} %---------------------------------% %%% BEGIN DOCUMENT \begin{document} \maketitle \tableofcontents \newpage %% ------------------------- %% \section{Introduzione} 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: \href{http://tautocrono.it}{tautocrono.it}.\\ Si può accedere usando le credenziali: \begin{center} \begin{tabular}{||c|c||} \hline Username & Password \\ \hline Guest & \\ \hline \end{tabular} \end{center} 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 \texttt{-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 \textit{testFiles}. Gli oggetti vengono creati nella directory \textit{obj/}, mentre gli eseguibili vengono creati nella directory \textit{build/}. La directory \textit{src/} contiene il codice che fa parte del main del server e del client; il resto del codice è contenuto nella directory \textit{lib/}. È stata implementata sia la politica di rimpiazzamento FIFO che la politica LRU. %% ------------------------- %% \section{Server} Il server prende come unico argomento il path al file di configurazione. Un esempio di file di configurazione è \texttt{config.ini} presente nella root del progetto. La struttura del file è analoga a quella di un file \href{https://en.wikipedia.org/wiki/INI_file}{INI}, quindi l'ordine degli argomenti dentro a sezione è irrilevante. Il file di configurazione viene letto da una libreria di "\textit{terza parte}" ottenuta da \href{https://github.com/rxi/ini}{rxi/ini}. Si sarebbe potuto usare la libreria \href{https://gitlab.gnome.org/GNOME/glib}{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 \texttt{strsep} invece di \texttt{strtok} o \texttt{strtok\_r} sia nel programma server che client. Il codice è stato adattato leggermente da quello presente nella libreria C GNU (\href{https://sourceware.org/git/?p=glibc.git;a=blob;f=string/strsep.c;h=b534a1ec17fd2e91087af04abe1c3f1ac3e74ce0;hb=HEAD}{strsep}) in modo da utilizzare la funzione omonima su piattaforme BSD e MacOS. \subsection{Main} Il thread principale accetta le connessioni in arrivo da i client su un socket di tipo \texttt{AF\_UNIX} con nome di default \textit{socket}. Viene interrotto dal thread \texttt{sighandler\_thread} se ricevuto un segnale fra: \texttt{SIGHUP}, \texttt{SIGINT} o \texttt{SIGQUIT}. \subsection{serverWorker} Il thread main dopo aver accettato la connessione di un client crea un thread "\textit{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 \textit{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 \textit{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 \texttt{waiting\_t}. La richiesta accodata non è quindi gestita dal thread corrente, ma dal thread che rilascerà la lock al file associato. Si evitano quindi \textit{polling} o l'utilizzo di \textit{condition}. \subsection{sighandler\_thread} Il thread gestisce i segnali in arrivo al server. Se il segnale ricevuto è di tipo \texttt{SIGINT} o \texttt{SIGQUIT}, il server termina prima possibile. Se il segnale ricevuto è del tipo \texttt{SIGHUP} invece si attende che ogni worker abbiano servito le richieste dei client precedentemente connessi. %% ------------------------- %% \section{Storage} Il server gestisce la memorizzazione dei file tramite la libreria \textit{fileQueue}. Nel header file \textit{fileQueue.h} la costante \texttt{ALGORITHM} imposta la politica di rimpiazzamento. Le funzioni che differiscono in comportamento sono: \texttt{dequeueN}, \texttt{lockFileInQueue}, \texttt{unlockFileInQueue}, \texttt{openFileInQueue}, \texttt{find}, \texttt{request}, \texttt{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 \texttt{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: \texttt{size} e \texttt{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 \texttt{size}, lasciando invariato la dimensione \texttt{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. %% ------------------------- %% \section{Logging} Il server usa la libreria "\texttt{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: \texttt{taglia\_write}, \texttt{taglia\_log}. \texttt{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. %% ------------------------- %% \section{Client} Oltre alle funzioni di API richieste dalla specifica è stata implementata la funzione \texttt{setDirectory}, perchè si è interpretata come se le opzioni \texttt{-d} e \texttt{-D} dovessero poter essere associate a più di un comando. Tuttavia questa funzionalità non è presente nel client in modo diretto dato che vengono inserite \texttt{-d}/\texttt{-D /dev/null} fra due opzioni \texttt{-w}/\texttt{-W} o \texttt{-r}/\texttt{-R} successive. L'opzione \texttt{-d /dev/null} o \texttt{-D /dev/null} è stata ottimizzata leggermente in modo da non fare chiamate di sistema. \\ Il client esegue prima l'opzione \texttt{-f}, in seguito l'opzione \texttt{-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. \begin{center} \begin{tabular}{|c|l|} \hline Number & Meaning \\ \hline 2\gry{*} & positive completion reply \\ \hline 4\gry{*} & transient negative completion reply (command not executed) \\ \hline 5\gry{*} & permanent negative completion reply (errors) \\ \hline \hline \gry{*}0 & syntax \\ \hline \gry{*}1 & information \\ \hline \gry{*}2 & connection \\ \hline \gry{*}5 & file system \\ \hline \end{tabular} \end{center} Di seguito una tabella in cui si associa ogni numero al codice usato: \begin{center} \begin{tabular}{|c|l|c|} \hline Number & Meaning & Code \\ \hline \hline 20 & OK & \texttt{MEOK} \\ \hline \gry{21} & \gry{not used} & \gry{\texttt{-}} \\ \hline \gry{22} & \gry{not used} & \gry{\texttt{-}} \\ \hline 25 & file purged & \texttt{MEFP} \\ \hline \hline \gry{40} & \gry{not used} & \gry{\texttt{-}} \\ \hline \gry{41} & \gry{not used} & \gry{\texttt{-}} \\ \hline 42 & shutting down & \texttt{MESD} \\ \hline 45 & requested file action not taken & \texttt{MENT} \\ \hline \hline 50 & syntax error & \texttt{MESY} \\ \hline \gry{51} & \gry{not used} & \gry{\texttt{-}} \\ \hline \gry{52} & \gry{not used} & \gry{\texttt{-}} \\ \hline 55 & server error & \texttt{MESE} \\ \hline \end{tabular} \end{center} Il client invia per primo la dimensione del messaggio come \texttt{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 \texttt{int64\_t} e poi successivamente il file. %% ------------------------- %% \end{document}