Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema...

128
Monitoring delle system call del sistema operativo Linux LibeRTOS Cristofaro Gozzolino 534/753 25 maggio 2006

Transcript of Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema...

Page 1: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Monitoring delle system call del

sistema operativo Linux LibeRTOS

Cristofaro Gozzolino 534/753

25 maggio 2006

Page 2: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Indice

1 Introduzione 41.1 Caratteristiche del kernel . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.2 Sviluppo, testing, monitoraggio dell’attivita del kernel . . . . . . . . . . . . . 51.3 Strumenti a supporto dello sviluppatore . . . . . . . . . . . . . . . . . . . . . 61.4 Presentazione LibeRTOS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1.4.1 Descrizione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 71.5 Presentazione DSKI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

1.5.1 Descrizione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8

2 Descrizione del tool DSKI/DSUI 112.1 Utilizzo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.1.1 Creazione dello spazio dei nomi . . . . . . . . . . . . . . . . . . . . . . 112.1.2 Parsing dello spazio dei nomi . . . . . . . . . . . . . . . . . . . . . . . 122.1.3 Abilitazione delle entita . . . . . . . . . . . . . . . . . . . . . . . . . . 142.1.4 Strumentazione . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.1.5 Compilazione ed esecuzione . . . . . . . . . . . . . . . . . . . . . . . . 162.1.6 Post–Processing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

2.2 Entita . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.2.1 Eventi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.2.2 Contatori . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182.2.3 Intervalli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.2.4 Istogrammi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192.2.5 Oggetti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

2.3 Esempi . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202.3.1 DSKI - Eventi di schedulazione preinseriti . . . . . . . . . . . . . . . . 202.3.2 DSUI - Eventi e Contatori . . . . . . . . . . . . . . . . . . . . . . . . . 232.3.3 DSKI - Eventi per kmalloc . . . . . . . . . . . . . . . . . . . . . . . 29

2.4 Cenni sul funzionamento interno . . . . . . . . . . . . . . . . . . . . . . . . . 332.4.1 Il driver dstream . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332.4.2 Comunicazioni con il driver via ioctl . . . . . . . . . . . . . . . . . . 342.4.3 Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352.4.4 Il demone dski daemon . . . . . . . . . . . . . . . . . . . . . . . . . . 35

2.5 Realizzazione di filtri . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 362.5.1 Creazione di un file .filter . . . . . . . . . . . . . . . . . . . . . . . 362.5.2 Implementazione di un filtro . . . . . . . . . . . . . . . . . . . . . . . 39

1

Page 3: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

INDICE 2

3 Caso di studio 443.1 Confronto DSKI – KProbes/SystemTAP . . . . . . . . . . . . . . . . . . . . . 443.2 Workloads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

3.2.1 UnixBench . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 483.2.2 IOzone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 493.2.3 Workload MEMORY bound . . . . . . . . . . . . . . . . . . . . . . . . 50

3.3 Scopo degli esperimenti . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 513.3.1 Sottosistema di gestione delle System Call in Linux . . . . . . . . . . . 523.3.2 ISR come handler di System Calls . . . . . . . . . . . . . . . . . . . . 523.3.3 Contesto degli esperimenti . . . . . . . . . . . . . . . . . . . . . . . . . 53

3.4 Preparazione esperimenti con KProbes/SystemTAP . . . . . . . . . . . . . . 543.5 Preparazione esperimenti con DSKI . . . . . . . . . . . . . . . . . . . . . . . 54

3.5.1 Filtro event pdf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 603.5.2 Filtro event percent . . . . . . . . . . . . . . . . . . . . . . . . . . . 613.5.3 Filtro event tomysql . . . . . . . . . . . . . . . . . . . . . . . . . . . 62

4 Risultati sperimentali 634.1 Risultati KProbes/SystemTAP . . . . . . . . . . . . . . . . . . . . . . . . . . 63

4.1.1 Caso CPU bound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 634.1.2 Caso IO bound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 644.1.3 Caso MEMORY bound . . . . . . . . . . . . . . . . . . . . . . . . . . 69

4.2 Risultati DSKI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 744.2.1 Caso CPU bound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 794.2.2 Caso IO bound . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 804.2.3 Caso MEMORY bound . . . . . . . . . . . . . . . . . . . . . . . . . . 81

4.3 Conclusioni . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85

A Installazione LibeRTOS/DSKI 89

B Ulteriori esempi 92B.1 DSKI - Eventi per fork e alloc/free pages . . . . . . . . . . . . . . . . . . . . 92B.2 DSKI - Contatori strumentando un modulo . . . . . . . . . . . . . . . . . . . 101B.3 DSUI - Intervalli . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 103

C Filtri 110C.1 Il filtro event pdf . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

C.1.1 Definizione e costruttore . . . . . . . . . . . . . . . . . . . . . . . . . . 110C.1.2 Il metodo process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111C.1.3 Il metodo close . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

C.2 Il filtro event percent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114C.2.1 Definizione e costruttore . . . . . . . . . . . . . . . . . . . . . . . . . . 114C.2.2 Il metodo process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116C.2.3 Il metodo close . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116

C.3 Il filtro event tomysql . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118C.3.1 Definizione e costruttore . . . . . . . . . . . . . . . . . . . . . . . . . . 118C.3.2 I metodi process e close . . . . . . . . . . . . . . . . . . . . . . . . . 119

Page 4: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

INDICE 3

D Database e query 121D.1 Creazione database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121D.2 Query . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123

E Codici di errore 125

Page 5: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Capitolo 1

Introduzione

Quasi la totalita delle applicazioni per l’elaborazione dell’informazione risiede su sistemi dicalcolo gestiti da programmi sempre piu articolati e complessi che formano il cosiddetto siste-ma operativo. Non esiste una semplice definizione di sistema operativo ma ci si puo riferiread esso come al livello interposto tra l’hardware e le applicazioni d’utente che funge da inter-mediario, per queste ultime, onde nascondere l’eterogeneita e la complessita dell’architertturafisica che effettivamente esegue l’elaborazione. Un sistema operativo quindi non fa altro cherealizzare una macchina astratta su una fisica, occupandosi di gestire tutte le problematicheche inevitabilmente si vengono a creare nel momento in cui sulla stessa macchina – che presen-ta un limite massimo relativamente al numero di CPU, la quantita di memoria, il numero diinterfacce etc.– piu entita (chiamate processi) richiedono di elaborare informazione. Lo scopodi chi realizza un sistema operativo e allora quello di implementare un insieme di funzionalitache mirino a risolvere i problemi legati alla condivisione di risorse limitate. Oggi i SistemiOperativi in realta non si limitano solo alla risoluzione di tali problemi ma includono moltefunzionalita che in verita hanno come unico fine quello di rendere agevole e amichevole l’usodel sistema ad un utente poco esperto. L’aggiunta delle interfacce grafiche, delle applicazionimultimediali, dei browser e di tante altre applicazioni, dentro o accanto al sistema operativo,rende oggi ancora piu difficile stabilire il confine tra sistema operativo e applicazioni d’utenteo ancora peggio tra quello che e effettivamente utile per sfruttare appieno la macchina e quelloche e utile alla “vista” dell’utente.

In questo testo si fa riferimento al sistema operativo Linux, un sistema open source copertodalla liceza GPL che fu sviluppato all’inizio degli anni 90 da Linus Torvalds sull’esempiodella famiglia di sistemi operativi Unix. Questo sistema operativo ha avuto una rapidissimadiffusione e un enorme successo che continua a crescere tuttora; la sua fortuna e legataenormemente al fatto che esso si caratterizza come un grande progetto collaborativo a cuicontribuiscono ogni giorno persone di tutto il mondo, esperti o semplici appassionati, che siscambiano idee e opinioni e questo continuo dialogo ha dato vita a distribuzioni e versionisempre aggiornate e sempre piu stabili.

1.1 Caratteristiche del kernel

La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituitida un unico grande kernel (letteralmente una sola pietra) che si esegue interamente in unsolo spazio di indirizzamento in modalita privilegiata. Col termine kernel naturalmente si

4

Page 6: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 1. INTRODUZIONE 5

suole indicare l’insieme delle funzionalita che realizzano i meccanismi interni del sistemaoperativo ma si intuisce che e abbastanza difficile stabilire che cosa rientra o non nel kernel.All’opposto dei sistemi monolitici ci sono i sistemi a microkernel che invece sono supportatida un kernel estremamente minimo che svolge solo funzioni di base mentre il resto vienedemandato a dei processi che girano anche in modalita utente (anche se nelle ultime versionisuccede sempre meno spesso). Tali sistemi rispettano il principio “divide et impera” per cuirisultano costituiti da un piccolissimo kernel e tanti moduli che svolgono la funzione di serventiper offrire le ulteriori funzionalita. Linux in realta si presenta come un sistema monolitico macomunque modulare. In parole povere si potrebbe dire che il kernel di linux e costituito da uninsieme di funzionalita orizzontali (operazioni di base), che vengono compilate in una grandeimmagine binaria, e altre funzionalita verticali (operazioni specifiche), che vengono realizzatemodularmente e che non fanno percio parte dell’immagine binaria del kernel ma si eseguonocomunque in modalita privilegiata per cui sono parte del kernel. A livello di codice sorgente ladifferenza non esiste se non per il fatto che i sorgenti dei moduli vengono posizionati ciacunoin una cartella separata e in certi casi bisogna rispettare delle regole1. Nel momento in cui unprogrammatore desidera compilare il kernel deve innanzitutto configurare le varie opzioni ecio significa non solo stabilire il valore di alcuni parametri ma anche decidere cosa deve essereparte integrante del kernel e cosa viene lasciato fuori come modulo. Infatti per molte opzionic’e la possibilita di scegliere tra 3 stati:

Y (Yes) l’opzione viene selezionata e le funzioni che la realizzano faranno parte dell’imma-gine binaria del kernel che viene caricata all’atto della fase di boot;

M (Module) l’opzione viene selezionata e deve essere inclusa in un modulo quindi le opera-zioni che la realizzano faranno parte di un modulo compilato a parte e che deve esserecaricato on demand;

N (No) l’opzione non viene selezionata quindi le funzioni che la implementano semplicementenon sono compilate.

Stabilita la configurazione, il kernel viene compilato solo con le opzioni desiderate. Un’al-tra caratteristica importante del kernel di Linux e che esso e prelazionabile cioe anche i processidel kernel seguono una politica di schedulazione; inoltre solo a livello kernel e previsto l’im-piego dei thread che invece non esistono a livello utente in quanto a tale livello i processi sonogia sufficientemente leggeri2.

1.2 Sviluppo, testing, monitoraggio dell’attivita del kernel

Per modificare un kernel sara sufficiente modificare i sorgenti che contengono l’implementa-zione delle procedure interessate ricordando che non e possibile, a livello kernel, richiamarealcuna funzione delle librerie C per non appesantire il codice e che lo stack a livello kernelha dimensioni ridotte (4 o 8 KB). Se invece aggiungiamo dei sorgenti completamente nuovi enecessario modificare anche il Makefile del kernel e se vogliamo aggiunere dei nuovi moduli

1Questo succede se ad esempio una funzionalita puo essere inclusa nel kernel solo come modulo e non inaltro modo.

2Nel senso che tutte le informazioni che li riguardano (descrittore etc.) non li appesantiscono come avvienein altri sistemi operativi.

Page 7: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 1. INTRODUZIONE 6

bisogna rispettare le regole di creazione dei moduli. Una volta apportate le modifiche neces-sarie potrebbe essere utile testare il nuovo kernel e vedere se tutto procede secondo quanto cisi aspetta. Questo discorso naturalmente ha un valore generale perche potremmo essere inte-ressati in ogni caso a conoscere il comportamento di un programma in esecuzione, intendendoper comportamento il suo flusso di esecuzione nonche i dati che produce o consuma. Rac-cogliere queste informazioni per un programma utente e assai semplice grazie alla presenzadei debugger, i quali non fanno altro che inserire degli opportuni punti di interruzione dopotutte (tracing) o alcune istruzioni (breackpoint). Queste interruzioni permettono all’utente diindagare sul programma e in particolare e possibile conoscere le informazioni relative al con-testo del processo (contenuto dei registri del processore etc.) nonche evidenziare il contenutodelle locazioni di memoria. In qualunque momento, l’utente, attraverso l’immissione di uninput, puo consentire al programma il proseguimento normale della sua esecuzione che verrainterrotta al prossimo breackpoint. Si potrebbe pensare di applicare il medesimo meccanismodi indagine al livello kernel ma cio non e possibile perche sarebbe necessario interrompere delleprocedure che offrono servizi all’intero sistema e questo provocherebbe degli effetti impredi-cibili nonche indesiderati. Basti pensare a cosa seccederebbe se interrompessimo l’esecuzionedi una regione critica: tutte le entita che vorrebbero eseguirla rimarrebbero in attesa per untempo estremamente elevato. L’idea che fa uso dei breakpoint non va pero completamentescartata; anche a livello kernel infatti dovra essere inserito una specie di breakpoint (che chia-meremo punto di strumentazione) ma il processo non deve interrompersi quando lo attraversae in qualche modo dovranno essere salvate da qualche parte le informazioni desiderate.

1.3 Strumenti a supporto dello sviluppatore

Il nostro problema e quello di trovare un modo per poter indagare sull’attivita dei processidel kernel senza doverli interrompere. A tal scopo la soluzione piu semplice consiste nell’usarein maniera copiosa la chiamata della procedura printk la quale, similmente alla printf dellalibreria stdio.h, consente di stampare le informazioni passate in ingresso sul dispositivo dioutput predefinito. L’unica differenza consiste nel fatto che a livello del kernel la printk scrivesul file /var/log/messages e non sul video. Adottando questa scelta e pero inevitabile doverinserire dei punti di strumentazione in ogni locazione del kernel che si desidera monitoraree naturalmente, in seguito a qualunque cambiamento, sara necessario ricompilare il kernel!Ci sono inoltre altri aspetti da prendere in considerazione. Una volta che i dati vengonoscritti nel file /var/log/messages, essi debbono in qualche modo essere catturati in brevetempo altrimenti, data la dimensione limitata del file stesso, i nuovi dati sovrascrivono quelliprecedenti. A tutto cio si aggiunge infine il grande problema di dover in ogni caso elaborare“a mano” i risultati e le informazioni ottenute. Per cui ne consegue che se le informazioni daraccogliere sono relativamente poche e non si producono con molta frequenza la soluzione chefa uso della printk puo anche andar bene altrimenti va scartata dal principio.

Fino alla versione 2.4 del kernel gli sviluppatori non avevano alternative all’impiego dellaprintk ma dalla versione 2.6 sono nati 3 strumenti che consentono di analizzare l’attivita delkernel. Gli strumenti seguono comunque l’idea di base: fissare un punto di strumentazione ecatturare le informazioni che poi verranno scritte da qualche parte. Gli strumenti in questionesono DSKI, KProbes, SystemTAP.

DSKI e stato sviluppato alla Kansas University ed e lo strumento che viene approfonditoin questo testo; esso viene descritto nelle sezioni successive per cui in questo paragrafo ci

Page 8: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 1. INTRODUZIONE 7

limitiamo a ricordare che il funzionamento di DSKI non differisce radicalmente da quello dellachiamata alla printk ma ci sono notevoli vantaggi per quello che concerne l’elaborazione deidati ottenuti.

KProbes e invece parte integrante del kernel di Linux dalla versione 2.6 e risolve il grandeproblema della ricompilazione del kernel offrendo un meccanismo di probing dinamico basatosulla conoscenza degli indirizzi di memoria in cui vengono mappate le funzioni del kernel. Siricordi che tali indirizzi sono fissi per ogni kernel e sono ricavabili facilmente dalla mappadi sistema generata dalla compilazione. KProbes pero non e molto agevole per salvare leinformazioni ottenute dal monitoraggio ne per elaborarle.

SystemTAP infine e uno strumento sviluppato da un gruppo di societa (tra cui IBM eRed Hat) che completa KProbes. Esso e molto piu potente di KProbes perche sfrutta leinformazioni di debug (informazioni utili a strumentare anche la singola riga di codice) manon fornisce un valido aiuto nell’elaborazione dei risultati. Nel testo esamineremo un casosperimentale in cui vengono usati tutti e tre gli strumenti approfondendo l’impiego di DSKI.Per conoscere in modo dettagliato anche gli altri 2 strumenti e possibile consultare la [TESIDI PAOLO].

1.4 Presentazione LibeRTOS

Lo strumento che ci proponiamo di analizzare nel testo, DSKI, e parte integrante del par-ticolare kernel LibeRTOS sviluppato alla Kansas University per cui in questa sezione for-niremo alcune informazioni generali su questo kernel specifico. Per maggiori informazionisull’installazione del kernel nonche dell’interfaccia si faccia riferimento all’appendice A.

1.4.1 Descrizione

Il kernel LibeRTOS e stato realizzato per migliorare le prestazioni dei sistemi DRE (Distribu-ted and Real time Embedded). Questi sistemi sono diffusi sempre con maggior frequenza inmolti settori come quello industriale o militare. Si ricordi che le applicazioni Real Time sonoparticolari applicazioni dove la correttezza dell’esecuzione non e legata solo ad aspetti logici(se fa bene quello che deve fare) ma anche ad aspetti temporali (se fa in tempo le cose chedeve fare). Il tempo di esecuzione (ma anche la reattivita dell’applicazione) debbono quindirispettare dei vincoli piu o meno stringenti (a seconda che l’applicazione sia hard real–time osoft real–time) e la violazione dei vincoli puo portare a situazioni anche molto pericolose perla vita delle persone (basti pensare a cosa potrebbe succedere se fallisse il sistema di controllodi un velivolo).

In seguito a tali considerazioni ci si puo chiedere come possa un sistema operativo garantireun miglioramento della condizioni di esecuzione in modo da favorire le applicazioni real–time.La risposta piu semplice da dare e che bisogna intervenire sul sistema di schedulazione deiprocessi. Si sa infatti che la procedura di scheduling di un sistema a partizione del tempogestisce l’uso della CPU con un algoritmo che “scaccia” un processo dalla CPU non appenascade la slice di tempo a lui destinata e seleziona un nuovo processo dalla coda dei processiready. E’ evidente che un sistema del genere non offre alcun vantaggio alle applicazioni real–time; un passo in avanti e quello di associare ai processi real–time una maggiore prioritacome spesso viene fatto. Il sistema operativo Linux in effetti assegna alle applicazioni Real

Page 9: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 1. INTRODUZIONE 8

Time una priorita compresa tra 0 e 99 e ai processi normali da 100 a 1393. Gli autori diLibeRTOS si sono in effetti concentrati proprio sul sistema di schedulazione dei processi e lohanno modificato per avvantaggiare le applicazioni real–time. Una descrizione esaustiva delmeccanismo implementato esula dagli scopi di questo testo ma forniremo alcune informazioniminime.

Il sistema adottato dagli autori di LibeRTOS e chiamato “Group Scheduling” e si trovaimplementato nei sorgenti della cartella drivers/group sched/. Come suggerisce il nomeesso consente di raggruppare i task secondo le loro caratteristiche e di selezionare per ognigruppo il metodo di schedulazione migliore. Questo meccanismo e quindi molto piu flessibiledi quello supportato di default da Linux perche quello funziona in generale ma puo non andarbene per alcune applicazioni soprattutto se i processi in gioco hanno tempi di computazionemolto diversi. I gruppi definiscono poi una gerarchia e ogni gruppo puo essere elemento di altrigruppi. Ad esempio ci puo essere il gruppo che utilizza il normale scedulatore di Linux e quindidi esso faranno parte i processi normali; un altro gruppo puo essere quello di applicazioni cheimpiegano lo streaming video e usa quindi un algolritmo diverso etc. Quando viene selezionatoun gruppo automaticamente parte lo schedulatore con il metodo di scedulazione predefinitoper quel gruppo e viene selezionato un processo appartenente al gruppo.

1.5 Presentazione DSKI

Nella sezione precedente sono stati esposti i motivi che hanno portato alla realizzazione delkernel LibeRTOS; ci si chiede a questo punto cosa c’entri il probing del kernel con un sistemaoperativo che fornisce uno schedulatore per migliorare il meccanismo di selezione delle appli-cazioni real–time. Analizzando i sorgenti del kernel di LibeRTOS e possibile notare l’aggiuntadella cartella drivers/dstream/. La cartella contiene i sorgenti che realizzano l’interfacciaDSKI che viene usata per il probing del kernel. Il group scheduling puo benissimamente farea meno di tale interfaccia ma essa e stata realizzata proprio per testare lo scheduler. Infatti,come si potra notare negli esempi forniti piu avanti nel testo, con DSUI/DSKI e possibilemisurare l’intevallo di tempo che separa due eventi. Se il primo evento lo associamo allapartenza di un processo real–time e il secondo alla terminazione si puo ad esempio calcolareil tempo di esecuzione e comprendere se la deadline viene rispettata. DSKI pero puo essereusato per fare analisi anche piu dettagliate per cui, in questo testo, siamo interessati ad essocome strumento di probing piu che come strumento di testing del “Group Scheduling” comeprobabilmente e stato concepito in partenza. Nella prossima sezione daremo uno sguardo altool mentre nel prossimo capitolo lo analizzeremo in dettaglio.

1.5.1 Descrizione

Il kernel LibeRTOS mette a disposizione dell’utente l’astrazione di “DataStream”, ossia unflusso di dati in formato standard che puo essere generato sia dal kernel che dalle applicazioniutente. Tali informazioni vengono generate utilizzando un’interfaccia identica sia a livelloutente, DSUI (DataStream User Interface), che a livello kernel, DSKI (DataStream KernelInterface). Sfruttando DSKI/DSUI e possibile registrare tutta una serie di informazioni ri-guardanti il flusso di controllo, le quali possono essere ottenute ed esaminate attraverso un

3Naturalmente si tratta di una niceness quindi i processi con il valore piu alto sono i piu simpatici perchehanno minore priorita e quindi lasciano piu facilmente la CPU agli altri.

Page 10: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 1. INTRODUZIONE 9

Nome Descrizionensedit Consente di generare uno o piu file di definizio-

ne dello spazio dei nomi (*.ns) con le relativefamiglie ed entita.

xpconfig Consente di definire un file di abilitazione(*.dski o *.dsui) che permetta di stabilire leentita da cui si e effettivamente interessati aricevere delle informazioni.

filtreconfig Consente di creare un filtro da applicare ai da-ti grezzi. Il filtro puo essere ottenuto dallacombinazione in pipeline di quelli gia presenti.L’utility non consente di definirne dei nuovi.

ds visualizer.py Consente di creare dei grafici basati su gruppicaricando un opportuno file di configurazione.

Tabella 1.1: Lista delle utility grafiche fornite dalla piattaforma.

Nome dsui-parse.pyImpiego dsui-parse.py -n <nome>.ns -t <nome>Descrizione Consente il parsing dei file *.ns nel caso DSUI.Nome dski-parse.pyImpiego dski-parse.py -n <nome1>.ns ... -n <nomek>.nsDescrizione Consente il parsing dei file *.ns nel caso DSKI.Nome dski daemonImpiego dski daemon -e <nome>.dskiDescrizione Avvia il demone che, fornito il file di abilitazione, cattura i dati grezzi

necessari e li salva in forma binaria.Nome dstream filter.pyImpiego dstream filter.py -c filtro.filterDescrizione Consente di applicare il filtro dato in fase di post–processing.

Tabella 1.2: Lista delle utility di base fornite dalla piattaforma.

insieme di utility messe a disposizione dalla piattaforma stessa e realizzate nel linguaggio discripting Python. Gli elenchi ed il ruolo di ciascuna utility sono mostrati nelle tabelle 1.1 e1.2; piu avanti nel testo comprenderemo appieno il loro significato.

L’interfaccia DSKI/DSUI identifica sia un programma utente che il sistema operativostesso come sorgenti di dati “grezzi”; questo insieme di dati viene astratto come un flussocontinuo che prende appunto il nome di DataStream, e che viene salvato in forma binariaall’interno di un file, oppure puo essere letto attraverso una socket da un altro processo. Unelemento di informazione viene generato nel momento in cui un thread di esecuzione raggiungeun punto di strumentazione.

Esistono due tipi principali di dati coinvolti nel processo di strumentazione. Il primotipo e quello direttamente generato dalla sorgente di informazione e puo essere suddivisoulteriormente in quattro tipi:

Evento Questo tipo indica il verificarsi di un determinato evento, come per esempio l’ese-

Page 11: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 1. INTRODUZIONE 10

cuzione di una particolare istruzione, il cambiamento di stato di un processo etc., ed emolto utile nel caso in cui si voglia strumentare il flusso di controllo.

Contatore Questo tipo memorizza il numero di volte in cui il punto di strumentazione adesso relativo e stato attraversato. Risulta pertanto utile nel caso in cui si voglia teneretraccia del numero di volte che un evento si e presentato.

Intervallo Viene utilizzato per misurare il tempo intercorrente tra il verificarsi di due par-ticolari eventi.

Istogramma Viene utilizzato per registrare una serie di statistiche su un certo periodo ditempo.

Oggetto Viene utilizzato per collezionare strutture dati del kernel.

Il secondo tipo di dati sono informazioni derivate che si ottengono attraverso l’attivitadi post–processing sull’insieme dei dati grezzi registrati. Un esempio e il filtraggio dei dati,oppure la loro manipolazione per ottenere un formato comprensibile all’utente. E’ evidente giada questa panoramica che l’interfaccia DSKI presenta il grosso svantaggio di dover inserirei punti di strumentazine dentro il codice sorgente del kernel. In quanto a supporto per ilpost–processing, pero, nessuna soluzione sembra essere migliore di DSKI!

Page 12: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Capitolo 2

Descrizione del tool DSKI/DSUI

2.1 Utilizzo

Le interfacce DSUI e DSKI presentano meccanismi simili per la strumentazione del codice; illoro utilizzo prevede i seguenti passi:

1. creazione dello spazio dei nomi ossia assegnazione di identificativi simbolici alle entitache strumentano il codice;

2. generazione moduli per la strumentazione;

3. abilitazione delle entita che strumenteranno il codice1;

4. strumentazione dell’applicazione;

5. compilazione ed esecuzione;

6. attivita di analisi tramite il post-processing.

2.1.1 Creazione dello spazio dei nomi

Come gia detto, DSUI viene utilizzato per strumentare una qualsiasi applicazione utente,DSKI per strumentare un qualunque modulo o sottosistema del kernel. Il primo passo nelloro utilizzo consiste nello scegliere cosa strumentare e quali informazioni registrare. Perfar questo si definisce un file dello spazio dei nomi (<nome>.ns)2 che racchiude l’insieme delledefinizioni delle entita da registrare attraverso degli identificativi simbolici ai quali e associatoun ID numerico; a loro volta le entita sono raggruppate in famiglie per organizzare meglio ilprocesso di strumentazione. Per generare i namespace file e possibile utilizzare l’utility nseditdell’insieme kusp, la quale presenta un’interfaccia grafica amichevole3, oppure e possibilescriverli attraverso un qualsiasi editor di testo4. Un namespace file deve avere una strutturadel genere:

1Questo passo puo in effetti essere fatto anche in seguito, e sufficiente che preceda l’esecuzione del programmastrumentato.

2Da questo punto in poi adotteremo la convenzione per cui <nome> e il nome scelto dal programmatore peril progetto da esaminare.

3Piu in avanti nel testo verra mostrato un esempio concreto che fa uso della suddetta utility.4Dal momento che in realta un namespace file e la rappresentazione di una tupla del linguaggio Python.

11

Page 13: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 12

#!lib.parsers.ns_parser_v1namespace {

desc = "Spazio dei nomi di esempio"family ESEMPIO_FAMILY 1 {

desc = "Una Famiglia di esempio"shortdesc = "Esempio"

event ESEMPIO_EVENT 0 {desc = "Un esempio di evento"shortdesc = "Esempio"kernelf = ""printf = "print_int"

}

}}

In questo esempio e stata definita la famiglia ESEMPIO FAMILY a cui e stata assegnato l’ID1; in questa famiglia e stato inserito l’ evento ESEMPIO EVENT con ID 0. Le altre righe servonoa completare la descrizione della famiglia e delle entita e verranno analizzate nell’esempiopratico fornito piu avanti nel testo.

2.1.2 Parsing dello spazio dei nomi

Definito il file dello spazio dei nomi (<nome>.ns), e necessario effettuare un parsing su diesso attraverso le utility messe a disposizione dalla piattaforma. Esistono due utility diversea seconda del parsing da eseguire e cioe se esso riguarda DSUI o DSKI benche le utility sicomportino in maniera simile.

DSUI

Cominciamo con DSUI. L’utility da usare per eseguire il parsing di uno spazio dei nomi definitoper strumentare una applicazione d’utente e dsui-parse.py, da usarsi con un comando deltipo:

dsui-parse.py -n <nome>.ns -t <nome>

L’utility si installa automaticamente nella directory /usr/bin quindi e possibile richia-marla da un qualunque percorso. Essa generera tre file:

<nome> dsui table.h Contiene un insieme di macro per inizializzare la piattaforma di stru-mentazione.

<nome> dsui families.h Contiene le macro necessarie per inserire i punti di strumentazione.

<nome> dsui vars.c Contiene le dichiarazioni delle entita con cui strumentare il codice.

Questi file verranno utilizzati per strumentare l’applicazione utente come sara spiegatopiu avanti. Va precisato che ovviamente tali file vengono posizionati, per esplicita volonta

Page 14: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 13

del programmatore, nella stessa directory in cui conserviamo tutti i file che serviranno pereseguire la strumentazione della particolare applicazione (spazio dei nomi, file di abilitazione,filtri...), mentre ben diversa e la situazione per il caso DSKI.

DSKI

Il caso DSKI risulta leggermente diverso. L’utility per eseguire il parsing di uno spazio deinomi definito per strumentare il kernel e dski-parse.py, da usarsi con un comando del tipo:

dkui-parse.py -n <nome1>.ns -n <nome2>.ns ... -n <nomek>.ns

La prima cosa da precisare e che la suddetta utility non si installa automaticamente nelladirectory /usr/bin come nel caso di dsui-parse.py. Perche? Il motivo sta nel fatto chel’utility viene usata per il parsing dei file *.ns definiti per il kernel. Si considera scontatoquindi che essa non verra utilizzata di frequente ma in teoria una sola volta e precisamentedopo che e stato deciso che cosa si vuole strumentare e quindi quali famiglie ed entita sononecessarie. Essa si trova precisamente nel percorso <RootKernel>/scripts/dski5. Nellastessa directory si troveranno anche tutti i file *.ns che vengono definiti per la strumentazionedel kernel. Infatti il comando non prende in ingresso un solo spazio dei nomi ma tutti i file*.ns che si trovano nella stessa cartella. L’utility generera quattro file:

datastream table kernel.h Semplice file di sistema

datastream families.h Contiene le macro necessarie per inserire i punti di strumentazione.

datastream table kernel.c Contiene le dichiarazioni delle entita con cui strumentare ilcodice.

family-config.in Contiene informazioni di configurazione delle famiglie di entita definiteper la strumentazione. Viene utilizzato dal sistema di compilazione kbuild durante laconfigurazione del kernel.

Questi file saranno utilizzati, invece, per strumentare il kernel. Da notare che in tal casola nomenclatura dei file ottenuti non e a scelta dell’utente ma e standard perche i file farannoparte del codice sorgente del kernel stesso. Anche la loro posizione non deve essere casualema devono essere inseriti in directory ben precise ossia:

datastream table kernel.h in <RootKernel>/include/linux

datastream families.h <RootKernel>/include/linux

datastream table kernel.c <RootKernel>/drivers/dstream

family-config.in <RootKernel>/drivers/dstream

Se i file non vengono sovrascritti a quelli presenti gia nelle directory specificate, ovvia-mente, all’atto della compilazione non sara possibile accorgersi di nuove famiglie o entita equindi, nel caso siano stati inseriti dei punti di strumentazione, verranno lanciati una serie dierrori di mancata definizione.

5Con <RootKernel> si intende il percorso in cui sono locati i sorgenti del kernel. Una convenzione assaidiffusa e porre i sorgenti nella directory /usr/src/<KERNEL>.

Page 15: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 14

2.1.3 Abilitazione delle entita

A questo punto, prima di scrivere il sorgente vero e proprio (o modificarne uno del kernel), enecessario stabilire quali entita o quali famiglie, tra quelle definite nello spazio dei nomi, vo-gliamo siano abilitate6. In parole povere bisogna stabilire quali tra le entita definite dovrannoeffettivamente loggare delle informazioni di strumentazione del codice. A tal scopo si deve de-finire un file di abilitazione (<nome>.dsui o <nome>.dski per DSUI e DSKI rispettivamente).Possiamo generare tale file attraverso l’apposita utility xpconfig o realizzandolo attraversoun qualsiasi editor di testo. Con riferimento all’esempio di namespace definito nella sezione2.1.1, e supponendo di dover strumentare un’applicazione d’utente, il file di abilitazine deveavere la struttura seguente:

#!lib.parsers.expt_parser_v1DSTRM_EVENT ESEMPIO_FAMILY 1 ESEMPIO_EVENT 0

Nel caso in cui vogliamo invece monitorare un’applicazione a livello kernel, alla sezioneprecedente vanno anteposte almeno le seguenti quattro righe:

EXPERIMENT_DURATION 5SNAPSHOT_FREQUENCY 10BINARY_TARGET "<nome>.bin"NAMESPACE_FILE "<nome>.ns"

che specificano la durata (in secondi) e la frequenza (in unita al secondo) dell’osservazionee il file binario in cui scrivere i dati grezzi nonche il file di definizione del namespace7.

Come si puo osservare, viene abilitato l’evento ESEMPIO EVENT della famiglia ESEMPIO FAMILYe nel secondo caso, oltre ad abilitare l’evento suddetto, precisiamo un monitoraggio delladurata di 5 secondi alla frequenza di 10 Hz.

2.1.4 Strumentazione

A questo punto siamo pronti per strumentare il codice. Il meccanismo risulta leggermentediverso nei casi DSUI e DSKI per cui li tratteremo separatemente.

DSUI

Per le applicazioni d’utente il programmatore dovra includere nel programma l’header dsui.he <nome> dsui table.h8. Il primo header serve per poter richiamare le macro di inizializza-zione e terminazione della piattaforma, il secondo per usare le macro di strumentazione delcodice. Per quanto riguarda l’inizializzazione, la macro da richiamare (evidentemente primache intervenga un punto di strumentazione) e

DSUI_INIT(<nome>.bin, <nome>.dsui);

6Ribadiamo che questa operazione potrebbe essere fatta anche in seguito ma deve di sicuro precederel’esecuzione dell’esperimento.

7In realta non e raro voler monitorare, nel caso DSKI, tanti eventi definiti in tanti diversi namespace filedistinti e che dovranno essere tutti specificati!

8Attenzione ad includere questi due file in quest’ordine!

Page 16: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 15

che come si vede prende in ingresso due nomi di file che sono, rispettivamante, il nomedel file binario in cui verranno salvate le informazioni di strumentazione, che nel capitolo 1abbiamo chiamato dati grezzi, e il nome del file di abilitazione che servira a stabilire qualientita devono effettivamente generare quei dati. Nel momento in cui si decide che non ci sonoulteriori punti da strumentare deve esser invocata la macro

DSUI_CLEANUP;

Tra le chiamate delle due macro precedentemente descritte, vanno inserite le chiamatedelle macro per la strumentazione vera e propria. Queste chiamate differiscono a seconda del-l’entita. Nel caso di eventi9 nel punto del codice associato all’evento sara posta una chiamatadel tipo:

DSTRM_EVENT_<nome famiglia>(EVENT <nome evento>, int <tag numerico>,size_t <dimensione del parametro>, void *<puntatore al parametro>);

Quindi riferendoci al nostro esempio, supponendo che vogliamo semplicemente l’informa-zione sull’istante in cui si verifica l’evento ESEMPIO EVENT10 scriveremo:

DSTRM_EVENT_ESEMPIO_FAMILY(ESEMPIO_EVENT, 0, 0, NULL);

DSKI

Il discorso e un po diverso nel caso in cui vogliamo strumentare il kernel. In tale situazionebisogna innanzitutto stabilire che cosa si vuole strumentare. Questo vuol dire che bisognaavere una conoscenza piu o meno approfondita dell’albero dei sorgenti del kernel. In effetti ilprimo passo consiste proprio nel trovare il file sorgente (*.c) che contiene il punto che si vuolestrumentare. Questo discorso e abbastanza generale nel senso che l’unico vincolo e dato dalfatto che il file deve far parte del codice sorgente del kernel e questo significa che possiamosceglierlo tra tutti i file dell’albero inclusi quelli che definiscono moduli che verranno caricati“on demand” e inclusi quelli relativi ad eventuali nuovi moduli definiti dal programmatore.Supponendo che il punto scelto si trovi nel file <nome>.c bisogna, come nel caso DSUI, inserirela (o le) macro di strumentazione. Come prima quindi scriveremo:

DSTRM_EVENT_ESEMPIO_FAMILY(ESEMPIO_EVENT, 0, 0, NULL);

ammesso che vogliamo catturare in quel punto l’evento ESEMPIO EVENT della famigliaESEMPIO FAMILY. A questo punto includiamo l’header datastream.h cioe scriveremo:

#include <linux/datastream.h>

perche l’header si trova proprio in <RootKernel>/include/linux. Questa operazionee simile a quella che in DSUI imponeva di includere i file dsui.h e <nome> dsui table.h.Infatti l’header datastream.h include al suo interno una serie di header che hanno un ruolosimile a quello dei due elencati prima e tra questi spicca datastream families.h che e proprioil file generato dallo spazio dei nomi come detto nella sezione 2.1.2 relativa al parsing.

9In effetti sono proprio gli eventi le entita usate nella maggioranza dei casi.10Di default quando si cattura un evento viene memorizzato nel file binario un timestamp dell’istante in cui

si verifica.

Page 17: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 16

2.1.5 Compilazione ed esecuzione

Arrivati a questo punto non ci resta che compilare ed eseguire gli esperimenti. Il discorsosulla compilazione risulta diverso nei casi DSUI e DSKI soltanto perche con DSKI biso-gna ricompilare tutto il kernel; relativamente all’esecuzione, invece, ci sono delle importantidifferenze.

DSUI

Il programma utente da strumentare andra collegato con il file <nome> dsui vars.c e conla libreria libdsui11; inoltre bisogna definire una serie di costanti del preprocessore tra cuiCONFIG DSUI, che abilita la piattaforma, e CONFIG DSTREAM <nome famiglia> per ogni singo-la famiglia da abilitare. L’utilizzo di costanti del preprocessore rende agevole la compilazionedell’applicazione in quanto nel momento in cui si vuole rilasciare la versione ultimata dell’ap-plicazione, e sufficiente non definire tali costanti senza modificare il codice. Riferendoci alnostro namespace file di esempio scriveremo:

gcc sorgente_1.c ... sorgente_n.c <nome>_dsui_vars.c -o <nome_eseguibile>-ldsui -DCONFIG_DSUI -DCONFIG_DSTREAM_ESEMPIO_FAMILY

Per mettere in esecuzione il programma basta semplicemente mandare in esecuzione il file<nome eseguibile> e si otterra alla fine il file <nome>.bin.

DSKI

Il caso DSKI e in effetti equivalente ma questa volta bisogna ricompilare il kernel! Quindila prima cosa da fare consiste nel settare le varie configurazioni attraverso i comandi makemenuconfig, make gconfig o simili. Nella fattispecie bisognera scegliere di compilare le infor-mazioni relative alle famiglie da utilizzare. Quindi nella sezione KU <nome> options scegliereKU Datastreams Kernel Interface e quindi DSKI Family Configuration. In questa se-zione e possibile selezionare le famiglie interessate tra le quali saranno certamente presentianche quelle definite dal programmatore come specificato nella sezione 2.1.1 e che presenteran-no l’etichetta (NEW). La selezione delle famiglie e equivalente all’abilitazione12 delle famiglieche in DSUI abbiamo eseguito da riga di comando quando nel compilare abbiamo aggiunto-DNOMEFAMIGLIA. A questo punto non resta che eseguire il comando make. Se ci sono modulidovra essere invocato anche il comando make modules install e quindi alla fine si invocheramake install che installera effettivamente il kernel preoccupandosi di aggiornare anche ilboot loader.

Una volta riavviato il sistema sara possibile eseguire un esperimento. Da notare che,diversamente dal caso DSUI, nel sorgente non e presente nessuna chiamata esplicita di inizi-lizzazione o terminazione della piattaforma. Infatti cio non e necessario in DSKI perche questechiamate sono in un certo modo automatiche. Inoltre il file di abilitazione delle entita, ossia<nome>.dski definisce al suo interno la durata dell’esperimento. Come fare pero a raccoglie-re le informazioni generate dai punti di strumentazione che, essendo inseriti in sorgenti del

11Questa e una grande limitazione dell’utilizzo di DSUI e DSKI. Infatti ogni volta che e necessariostrumentare una sezione del codice bisogna ricompilare l’applicazione o peggio ancora il kernel.

12Non bisogna confondere l’abilitazione a tempo di compilazione, che rende validi i punti di strumentazione,e quella definita attraverso il file delle abilitazioni che rende valida la cattura delle informazioni relative aquesti punti a tempo di esecuzione.

Page 18: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 17

kernel, probabilmente vengono attraversati di continuo? Adibito a tale funzione e il demonedski daemon richiamabile attraverso il comando seguente:

dski_daemon -e <nome>.dski

Il demone prende in ingresso il file delle abilitazioni e avvia l’esperimento per la duratain esso specificata. Si potrebbe dire che il demone invoca l’inizializzazione della piattaformaall’atto della sua chiamata e la terminazione dopo il tempo precisato nel file, catturando soloi dati relativi alle entita che risultano abilitate dal file stesso. Alla fine dell’esperimento, comeper DSUI, si ottiene il file binario che contiene i risultati grezzi della strumentazione.

2.1.6 Post–Processing

Una volta che e stata eseguita l’applicazione o avviato il demone, siamo in possesso di unfile <nome>.bin che contiene tutti i dati memorizzati dalle varie macro di strumentazione.Il file binario di per se non puo essere aperto ne compreso dall’utente. Proprio per questomotivo la piattaforma consente di interpretarlo e di applicargli degli speciali filtri per ottenerele informazioni desiderate.

Per cominciare la fase di post-processing e necessario, innanzitutto, definire un filtroattraverso la creazione di un file che potremo chiamare filtro1.filter. Per la creazionedi tale file vale il solito discorso e cioe possiamo usare un’apposita utility della piattaformadenominata filterconfig, che ha un’interfaccia grafica semplice da usare, oppure possiamoeditare il file con un editor di testo. Il file deve risultare come il seguente13:

dtd_path = /../../dtds

input_file:<nome>.bin # filenamebinary # file type# namespaces:/../../<nome>.ns

output_file:filtro1.xml # filenamexml # file type

filter utility.narrate {namespaces = [<nome>.ns]

}

Si vede che e necessario fornire alcune informazioni in input come il file binario e il file didefinizione del namespace. Si definisce inoltre dove devono essere memorizzate le informazionidi postprocessing, come un file xml (e di conseguenza il path per il file di interpretazionedenominato composite stream.dtd) e infine si elencano i vari filtri da applicare. Nell’esempioc’e un solo filtro che semplicemente narra quello che e accaduto durante il test, creando didefault un file chiamato narration.txt che elenca gli istanti relativi nei quali si verificanogli eventi.

13Per maggiori informazioni sulla realizzazione dei filtri si faccia riferimento alla sezione 2.5.

Page 19: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 18

2.2 Entita

Avendo dato uno sguardo a come debbono essere usate le macro per la strumentazione delcodice, e utile fornire una descrizione delle possibili entita che permettono la strumentazionestessa cioe eventi, contatori, intervalli, istogrammi e oggetti.

2.2.1 Eventi

Gli eventi sono le entita piu semplici, essi sono utilizzati per segnalare l’attraversamento diun determinato punto del codice da parte del flusso di controllo; oltre alla segnalazione diattraversamento, possono contenere anche una serie di informazioni utili che possono essereutilizzate in fase di postprocessing e che prendono il nome di extra-dati14. Tra le informazionipiu utili, gli eventi racchiudono il timestamp, cioe l’istante in cui si sono verificati, un tagnumerico (che puo essere utilizzato dall’utente per differenziare eventi simili fra loro), edun’informazione extra a scelta dell’utente.

Per inserire un evento nel codice si deve utilizzare la semplice macro:

DSTRM_EVENT_<nome famiglia>(EVENT <nome evento>, int <tag numerico>,size_t <dimensione del parametro>, void *<puntatore al parametro>);

Si noti che il parametro extra viene passato attraverso un puntatore a void e bisognaanche specificarne la dimensione; a priori, infatti, quando si definisce il namespace file, siseleziona anche la funzione che prende in consegna il dato extra per formattarlo in in un certomodo. Quest’ultima andra selezionata da un insieme di funzioni adibite a questo scopo comead esempio print int. Un esempio di utilizzo degli eventi, con uso degli extra-data e fornitonella sezione 2.3.2.

2.2.2 Contatori

I contatori sono entita altrettanto semplici, ma su di esse e definito un numero maggiore dioperazioni. Come suggerisce il nome, essi vengono utilizzati per contare il numero di volteche si verifica un evento, dove l’evento monitorato non necessariamente deve essere anchecatturato attraverso l’entita EVENT definita nella sezione precedente.

Le macro definite sul tipo contatore e che possono essere usate per la strumentazione sonoquattro:

DSTRM_INCR_COUNTER_<nome famiglia>(COUNTER <nome contatore>);

DSUI_ADD_TO_COUNTER_<nome famiglia>(COUNTER <nome contatore>, int <valore>);

DSUI_LOG_COUNTER_<nome famiglia>(COUNTER <nome contatore>);

DSUI_RESET_COUNTER_<nome famiglia>(COUNTER <nome contatore>);

Il loro compito e abbastanza intuitivo. La prima macro aggiunge un’unita al contatorementre la seconda aggiunge il valore specificato come parametro. La terza esegue l’effettivo logdel contatore (se non viene invocata non c’e modo di risalire al valore del contatore) e l’ultima

14Vedere l’esempio nella sezione 2.3.2

Page 20: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 19

riazzera il contatore stesso. Tutte le macro sono disponibili per l’interfaccia DSUI mentrel’interfaccia DSKI mette a disposizione esclusivamente la seconda perche le altre operazionivengono eseguite in automatico. Anche per i contatori un esempio di utilizzo e fornito nellasezione 2.3.2.

2.2.3 Intervalli

Gli intervalli sono entita a parte che vengono definite nei file *.ns ma che non entrano ingioco nel processo di manipolazione del codice sorgente. Cio significa che una volta eseguito ilparsing del file *.ns non verra generata alcuna macro che li riguardi e quindi il loro impiegonon e perfettamente esplicito. Un intervallo definisce il lasso di tempo che intercorre tra ilverificarsi di un evento, chiamato evento di “START”, e il verificarsi di un altro evento dettoevento di “END”15. Gli eventi di start e end possono appartenere a famiglie diverse cosı comel’intervallo stesso puo appartenere ad una famiglia a se stante. L’unico vincolo presente eche le famiglie debbono essere definite nello stesso file *.ns. Inoltre non e neppure necessarioche i punti di strumentazione relativi agli eventi siano inseriti nello stesso file sorgente neche vengano sollevati da parte dello stesso processo16. Naturalmente per ogni evento di startverificatosi ci deve essere un evento di end che si verifichi prima o poi altrimenti l’intervallonon si forma. Tutte le informazioni necessarie per definire un intervallo (start, end, processi...)possono essere fornite direttamente nella fase di post–processing. A tal scopo si veda l’esempionella sezione B.3

2.2.4 Istogrammi

Gli istogrammi, come suggerisce il nome, sono entita utilizzate appositamente per collezionaredati in maniera organizzata onde ottenere in fase di post–processing un grafico a barre chemostri l’occorrenza di eventi o simili. Per quanto concerne l’interfaccia DSUI, a disposizionedel programmatore ci sono 3 possibili macro:

DSUI_RESET_HISTOGRAM_<nome famiglia>(HISTOGRAM <nome istogramma>);

DSTRM_HISTOGRAM_<nome famiglia>(HISTOGRAM <nome istogramma>, int <valore>);

DSUI_LOG_HISTOGRAM_<nome famiglia>(HISTOGRAM <nome istogramma>);

Le tre macro vanno utilizzate nell’ordine cosı come sono elencate in quanto la prima azzerail valori statistici, la seconda fornisce un nuovo valore e la terza logga effettivamente i dati.Nel caso dell’interfaccia DSKI, invece, le macro disponibili sono 6:

DSTRM_HISTOGRAM_GRAFIC_FAM(HISTOGRAM <nome istogramma>, int <valore>);

DSTRM_HIST_ENTER_GRAFIC_FAM(HISTOGRAM <nome istogramma>);

DSTRM_HIST_TO_GROUP_ENTER_GRAFIC_FAM(HISTOGRAM <nome istogramma>,

15Questa nomenclatura e del tutto convenzionale, non e necessario nominare gli eventi con tali suffissi.16Ad esempio il punto di strumentazione relativo all’evento di start potrebbe trovarsi nel file slab.c ed essere

attraversato per opera del processo X mentre il punto di strumentazione relativo all’evento di end potrebbetrovarsi nel file page alloc.c ed essere attraversato per opera di Y.

Page 21: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 20

int <gruppo>);

DSTRM_HIST_TO_GROUP_EXIT_GRAFIC_FAM(HISTOGRAM <nome istogramma>,int <gruppo>);

DSTRM_HIST_TO_GROUP_EXIT_CYCLES_GRAFIC_FAM(HISTOGRAM <nome istogramma>,int <gruppo>);

DSTRM_HISTOGRAM_TO_GROUP_GRAFIC_FAM(HISTOGRAM <nome istogramma>,int <valore>, int <gruppo>);

La prima macro ha lo stesso identico ruolo che in DSUI cosı come le macro di EXIT possonoessere paragonate a quella di LOG di DSUI. Le macro di ENTER sono simili invece a quella diRESET. Da notare in tal caso l’aggiunta di un parametro che non esiste a livello DSUI cioe ilgruppo dell’istogramma che e una sorta di identificativo simbolico per raggruppare gli stessidati statistici.

Come per qualsiasi istogramma e possibile definire il valore minimo, massimo e il numerodei range con cui rappresentare i dati. Queste informazioni devono essere precisate nel file diabilitazione (*.dsui o *.dski) dell’esperimento. Per ottenere i grafici e necessario applicaredei filtri tra cui ricordiamo expressive.histogram graph che genera un file *.gnuplot euno *.dat. Attraverso il comando17 gnuplot *.gnuplot si ottiene un’immagine *.ps chemostra l’istogramma a barre proprio come nel caso dell’esempio relativo agli intervalli nellasezione B.3.

2.2.5 Oggetti

Gli oggetti sono in parte paragonabili agli intervalli. Anche per essi, infatti, le interfacceDSUI e DSKI non mettono a disposizione alcun tipo di macro che possa essere invocata perinserire un punto di strumentazione. Essi hanno il compito di collezionare dati, soprattuttoa livello kernel. Il loro uso rimane comunque scarso quindi non li approfondiamo.

2.3 Esempi

A questo punto, avendo fornito una descrizione generica di quelli che sono i passi da eseguireper strumentare il codice d’utente o del kernel e avendo analizzato a grandi linee le entitache entrano in gioco nella strumentazione, forniamo alcuni esempi concreti che consentanodi comprendere efficacemente i concetti precedentemente esposti. In tutti gli esempi fornitivengono usate le utility della piattaforma, le quali hanno un’interfaccia grafica semplice dausare e di cui spiegheremo l’uso fondamentale. E’ facile vedere che i file generati dalle utilitysono conformi con quanto detto in precedenza. Premettiamo che il kernel su cui vengonoeseguiti tutti gli esperimenti relativi al caso DSKI e quello 2.6.12-RT-V0.7.50-04-libertos.

2.3.1 DSKI - Eventi di schedulazione preinseriti

Questo primo esempio di DSKI che si propone e veramente semplice e veloce da eseguire. Vo-gliamo strumentare il file sched.c che realizza la funzione void sched schedule(void)

17Presupponendo che sia installato, considerando che non e fornito assieme alla piattaforma.

Page 22: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 21

che esegue l’operazione di schedulazione dei processi. Tale file sched.c e gia stato stru-mentato dagli autori di LibeRTOS, e facile infatti osservare al suo interno alcuni punti distrumentazione pre-inseriti:

DSTRM_EVENT(SCHEDULER_FAM, SWITCH_FROM, current->pid, 0, NULL);prev = context_switch(rq, prev, next);barrier();

DSTRM_EVENT(SCHEDULER_FAM, SWITCH_TO, current->pid, 0, NULL);

Tali eventi sono definiti, insieme alle loro famiglie, nel namespace file kernel.ns che sitrova in <RootKernelLibeRTOS>/scripts/dski/. Poiche in questo esempio non definiamoun nuovo spazio dei nomi ne aggiungiamo in qualche sorgente del kernel dei nuovi punti distrumentazione, non e necessario ricompilare il kernel ne rieseguire un parsing dei file *.ns.

Abilitiamo quindi gli eventi che ci interessano. Nel nostro caso siamo interessati solo a dueeventi: SWITCH FROM che si verifica proprio prima che avvenga un context switch e SWITCH TOche invece si verifica subito dopo. Avviamo xpconfig e dal menu Namespace scegliamo diaggiungere il namespace kernel.ns. Una volta caricato spuntiamo gli eventi di interesse,come mostrato in figura 2.1, e definiamo, come da figura 2.2, una durata dell’esperimeto di5 secondi, una frequenza di osservazione di 1 e come file di output dell’esperimento il fileswitch.bin. Salviamo il tutto come switch.dski.

Figura 2.1: Generazione file di esperimento dski.

Adesso dobbiamo avviare il demone di osservazione con il comando

dski_daemon -e switch.dski

Page 23: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 22

Figura 2.2: Impostazioni esperimento dski.

Alla fine troveremo un file switch.bin che contiene le informazioni riguardo ai contextswitch. Per interpretare questo file applichiamogli un filtro. Avviamo l’utility filterconfige come da figura 2.3 specifichiamo che vogliamo in uscita un file chiamato filtro1.xml(fornendo di conseguenza il path per il dtd) e che il file di input e il file binario switch.bin,aggiungendolo col pulsante in basso a sinistra. Spostiamoci nella sezione Namespace e colpulsante in basso a sinistra aggiungiamo il nostro namespace come da figura 2.4. Infine nellasezione Filters aggiungiamo un filtro che mostri solo gli eventi di tipo (SWITCH TO) e quindi,come da figura 2.5, scegliamo il filtro utility.name.

Figura 2.3: Creazione filtro - passo 1.

A questo punto eseguiamo il comando

dstream_filter.py -c filtro1.filter

e otterremo finalmente in uscita il file switch.xml che mostra tutti gli eventi catturatidel tipo SWITCH TO, oltre alle normali informazioni di timestamp come mostra il seguentepezzetto estratto da esso

Page 24: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 23

Figura 2.4: Creazione filtro - passo 2.

<ENTITY number="10" tag="2742" time_stamp="28918662172230"clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" ><EVENT name="SWITCH_TO" family="SCHEDULER_FAM" id="65" ></EVENT></ENTITY>

In questo caso ad esempio osserviamo che sono specificate alcune informazioni tra cui l’IDdell’entita, il tag, il tipo di entita etc. Analizzeremo in seguito tali informazioni e il lorosignificato.

2.3.2 DSUI - Eventi e Contatori

Come esempio di utilizzo di DSUI prendiamo il seguente file denominato prova.c

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>

int main(){

printf("Questa e’ una prova\n");int mf = open("/dev/random", O_RDONLY);int j = 0;

Page 25: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 24

Figura 2.5: Creazione filtro - passo 3.

for(; j < 10; j++) {int rand;read(mf, (void*) &rand, sizeof(int));printf("Numero: \%d\n", rand);

}

close(mf);return 0;}

Il codice riportato esegue un’operazione molto semplice. Viene aperto innanzitutto il file-device /dev/random che e una sorgente di numeri random18. Quindi vengono letti diecinumeri e stampati sul video. Vogliamo strumentare il codice, ottenendo informazioni nonsolo relative alla generazione di un numero random ma anche sapere quanti numeri generatisono positivi. Definiamo allora dall’inizio il nostro namespace nel file prova.ns. Avviamol’utility nsedit e cominciamo col creare un namespace file che chiamiamo prova.ns. Selezio-nato tale file, attraverso il menu Namespace e la voce New Family, aggiungiamo la famigliadi eventi PROVA EVENTS e la famiglia di contatori PROVA COUNTERS, come da figura 2.6. Nellafamiglia di eventi creiamo allo stesso modo un evento chiamato PROVA EVENTS RANDOM checattura la generazione di un numero random; nella figura 2.7 si osserva che per un evento epossibile specificare una funzione di print che puo operare su un dato extra associato all’e-vento. Nel nostro caso abbiamo scelto il valore print int onde memorizzare tra i dati delDataStream i numeri random stessi. Nella famiglia di contatori definiamo poi un contatorePROVA COUNTERS POSITIVES come mostrato in figura 2.8.

A questo punto eseguiamo il parsing del nostro namespace col comando

dsui-parse.py -n prova.ns -t prova

ottenendo i tre file18Tali numeri random, vengono creati con un meccanismo molto intrigante basato sulle interruzioni.

Page 26: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 25

Figura 2.6: Creazione spazio dei nomi - passo 1.

Figura 2.7: Creazione spazio dei nomi - passo 2.

prova_dsui_families.h prova_dsui_table.h prova_dsui_vars.c

Il file prova dsui table.h va incluso nel file prova.c per poter richiamare tutte le macrodi strumentazione relative all’evento e al contatore, ossia nell’ordine

DSUI_RESET_COUNTER_PROVA_COUNTERS(PROVA_COUNTERS_POSITIVES);DSTRM_EVENT(PROVA_EVENTS, PROVA_EVENTS_RANDOM, 0, sizeof(int), (void*)&rand);DSUI_INCR_COUNTER_PROVA_COUNTERS(PROVA_COUNTERS_POSITIVES);DSTRM_ADD_TO_COUNTER_PROVA_COUNTERS(PROVA_COUNTERS_POSITIVES,1);DSUI_LOG_COUNTER_PROVA_COUNTERS(PROVA_COUNTERS_POSITIVES);

Il file dsui.h va incluso per i motivi spiegati nella sezione 2.1.4. Adesso va creato un filedi abilitazione e quindi attraverso l’utility xpconfig creiamo il file prova.dsui facendo atten-zione a togliere il segno di spunto al campo DSKI come mostra la figura 2.9 e abilitando tuttele famiglie (e quindi tutti gli eventi e i contatori). Pertanto il file risultante dall’inserimentodei punti di strumentazione e:

#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>

Page 27: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 26

Figura 2.8: Creazione spazio dei nomi - passo 3.

Figura 2.9: Configurazione strumentazione dsui

// per abilitare le famiglie#ifdef ENABLE

#define CONFIG_DSUI#define CONFIG_DSTREAM_PROVA_EVENTS#define CONFIG_DSTREAM_PROVA_COUNTERS

#endif

#include <dsui.h>#include "prova_dsui_table.h"

int main(){

/* Inizializzazione della piattaforma */

Page 28: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 27

DSUI_INIT("prova.bin","prova.dsui");

/* Resetta il contatore PROVA_COUNTERS */DSUI_RESET_COUNTER_PROVA_COUNTERS(PROVA_COUNTERS_POSITIVES);

printf("Questa e’ una prova\n");int mf = open("/dev/random", O_RDONLY);int j = 0;

for(; j < 10; j++){int rand;read(mf, (void*) &rand, sizeof(int));

/* Genera l’evento PROVA_EVENTS_RANDOM */DSTRM_EVENT_PROVA_EVENTS(PROVA_EVENTS_RANDOM,

0, sizeof(int), (void*)&rand);

#ifdef ENABLEif (rand >= 0){

/* Incrementa il contatore */DSUI_INCR_COUNTER_PROVA_COUNTERS(

PROVA_COUNTERS_POSITIVES);

/* Aggiunge un’ulteriore unita al contatore */DSTRM_ADD_TO_COUNTER_PROVA_COUNTERS(

PROVA_COUNTERS_POSITIVES,1);

/*Memorizza il valore del contatore nel DataStream*/DSUI_LOG_COUNTER_PROVA_COUNTERS(

PROVA_COUNTERS_POSITIVES);

}#endif

printf("Numero: \%d\n", rand);

}

close(mf);

/* Disattivazione della piattaforma*/DSUI_CLEANUP;

return 0;}

Page 29: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 28

A questo punto compiliamo ma prima notiamo che nel file prova.c abbiamo definitouna costante di preprocessore ENABLE che useremo per abilitare in un sol colpo tutte lefamiglie che debbono esserlo in base a quanto spiegato nella sezione 2.1.5 e inoltre vie-ne utilizzata per compilare il blocco dell’if solo se effettivamente e abilitata la strumen-tazione. In aggiunta sul contatore invochiamo, all’atto dell’incremento, anche la macroDSTRM ADD TO COUNTER PROVA COUNTERS che aggiunge un’ulteriore unita allo stesso. Eseguia-mo quindi il comando

gcc prova.c prova_dsui_vars.c -o prova -ldsui -DENABLE

ottenendo il file eseguibile prova. Lo si esegue e otteniamo il file prova.bin come speci-ficato all’ingresso della macro DSUI INIT(). A questo punto non resta che definire un filtro.Con l’utility filterconfig creiamo un filtro con la stessa procedura descritta nella sezione2.3.1. Questa volta nella sezione Filters, come da figura 2.10, scegliamo utility.narrate inmodo da vedere per intero i dati generati19. Salviamo come prova1.filter ed eseguiamo ilcomando

Figura 2.10: Configurazione filtro narrate.

dstream_filter.py -c prova1.filter

ottenendo questa volta due file, narration.txt20 e prova1.xml. E’ interessante ispezio-nare il file xml e vedere come effettivamente il contatore venga incrementato21 solo quando ilnumero random generato e positivo; il valore del numero random e visto inoltre proprio comeun EXTRA DATA, come mostrato dal seguente frammento del file

<ENTITY number="1" tag="0" time_stamp="37880251466906"clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="PROVA_EVENTS_RANDOM" family="PROVA_EVENTS" id="64" ><EXTRA_DATA format="base64">

Y+yDTA==</EXTRA_DATA><EXTRA_DATA format="custom">

Value = 1283714147.000000</EXTRA_DATA></EVENT></ENTITY><ENTITY number="2" tag="0" time_stamp="37880253854498"

clock_id="localhost.localdomain"time_std="0" type="COUNTER" conv_ts="0" low_err="0" high_err="0" >

19Va precisato che in realta potremmo usare il filtro utility.null che effettivamente non fa altro chemostrare i dati generati ma esso non genera il file narration.txt.

20Generato automaticamente e di default dal filtro narrate.21Di due unita per quanto detto in precedenza.

Page 30: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 29

<COUNTER name="PROVA_COUNTERS_POSITIVES" family="PROVA_COUNTERS"id="128" count="2" first_updatetime="37880253839446"last_updatetime="37880253843690"/>

</ENTITY><ENTITY number="3" tag="0" time_stamp="37880254261770"

clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="PROVA_EVENTS_RANDOM" family="PROVA_EVENTS" id="64" ><EXTRA_DATA format="base64">

v1+mlg==</EXTRA_DATA><EXTRA_DATA format="custom">

Value = -1767481409.000000</EXTRA_DATA></EVENT>

Osserviamo che nello stralcio di file xml sono riportati gli extra data in vari formati. Adesempio i numeri random sono riportati in codifica base64 per default (in quanto qualsiasiextra dato viene riportato in tale formato) ed anche in formato custom ossia a seconda dicome e stato definito nel namespace file (nel nostro caso come un intero a causa della funzioneprint int).

2.3.3 DSKI - Eventi per kmalloc

I due esempi precedenti sono stati forniti onde spiegare l’utilizzo dell’interfaccia DSUI e delleutility grafiche per la generazione dei vari file. In questa sezione passiamo a fornire invece unesempio completo dell’utilizzo di DSKI cioe un esempio in cui viene richiesta la ricompilazionedel kernel. Supponiamo di voler strumentare la funzione del kernel kmalloc() per allocare,a livello kernel, un certo numero di byte addizionali di memoria con certe caratteristiche. Ilprimo passo da compiere e la creazione di un namespace file che supponiamo di chiamarekmalloc.ns. Essendo interessati semplicemente a catturare l’invocazione della funzione, sarasufficiente definire una famiglia e un evento come mostrato di seguito:

#!lib.parsers.ns_parser_v1namespace {

desc = ""family KMALLOC_FAM 21 {

desc = ""shortdesc = "Famiglia Kmalloc"event REQUEST_EV 0 {

printf = "print_int"shortdesc = "Richiesta di memoria"

}}

}

Questo file definisce la famiglia KMALLOC FAM con evento REQUEST EV. In particolare l’eventoe capace di stampare un extra dato in formato intero visto che siamo interessati a conoscereevidentemente il numero di byte che sono stati richiesti. Il file, per quanto detto nella sezione

Page 31: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 30

2.1.2, deve essere posto nella directory <RootKernelLibeRTOS>/scripts/dski dove ci sonoanche gli altri file *.ns generati dagli autori di LibeRTOS. Proprio per questo motivo l’IDdella nostra famiglia non puo essere casuale ma deve essere 21 essendo che sono state definitegia altre 21 famiglie (si parte da 0) dagli autori del kernel e poi perche la nostra famigliae in assoluto la prima che viene aggiunta dall’utente. Una volta costruito il namespace filebisogna eseguire tutte quelle operazioni tediose descritte nella sezione 2.1.2 (creazione file espostamento in directory precise del sistema). Proprio per questo motivo gli autori di LibeR-TOS forniscono un comando automatico che realizza tutti i passi. Il comando e incluso nelMakefile del kernel e precisamente alla label dskifamilies. Se vogliamo invocarlo bisogneramodificare il Makefile e aggiungere il nome del file *.ns generato alla lista di quelli che subi-ranno il parsing; aggiungiamo quindi -n kmalloc.ns. Bisogna ora invocare il comando makedskifamilies. Adesso e possibile inserire il punto di strumentazione nel sorgente del kernel.La funzione kmalloc e implementata nel sorgente <RootKernelLibeRTOS>/mm/slab.c. Laprima cosa da fare e includere l’header datastream.h; quindi si passa all’inserimento delpunto di strumentazione. La funzione kmalloc modificata risultera come segue:

void *__kmalloc(size_t size, unsigned int __nocast flags){

int dim;kmem_cache_t *cachep;dim = (int) size;

DSTRM_EVENT(KMALLOC_FAM, REQUEST_EV, 0,sizeof(int), (void*)&dim);

cachep = __find_general_cachep(size, flags);

if (unlikely(cachep == NULL))return NULL;

return __cache_alloc(cachep, flags);}

E’ stato sufficiente inserire la riga si strumentazione e un paio di righe per convertire iltipo opaco size t in intero (anche se forse non necessario22).

Una volta modificato il sorgente bisogna abilitare la compilazione dei punti di strumen-tazione; per fare cio eseguire il comando make menuconfig. Quindi selezionare la famigliaKmalloc (che compare con l’etichetta NEW) come segue:

KU Libertos options||--KU Datastreams Kernel Interface

||--DSKI Family Configuration

||-- [*] DSKI Calibration Tests Type1

22Si ricorda che una variabile di tipo opaco e una variabile di tipo sconosciuto o irrilevante ma nella maggiorparte dei casi e intera.

Page 32: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 31

|-- .....|-- [*] IP Layer tests|-- [*] Famiglia Kmalloc (NEW)|-- ....

A questo punto tutto e pronto per la ricompilazione del kernel e quindi si eseguano insuccessione i tre comandi

makemake modules_installmake install

Una volta riavviato il sistema siamo pronti per eseguire l’esperimento e quindi definiamoil file di abilitazione kmalloc.dski da fornire in ingresso al demone. Supponiamo di volereuna durata dell’esperimento pari a 10 secondi con frequenza di 1 specificando anche tutte lealtre informazioni necessarie (namespace, file di uscita...). Il file apparira come segue:

#kmalloc.dski#!lib.parsers.expt_parser_v1

EXPERIMENT_DURATION 5

# Snapshot Frequency

SNAPSHOT_FREQUENCY 1

# Binary Target

BINARY_TARGET "kmalloc.bin"

# Namespace File

NAMESPACE_FILE "usr/src/2.6.12-RT_LIBERTOS/script/dski/kmalloc.ns.ns"

# Enabled Entities

DSTRM_EVENT KMALLOC_FAM 21 REQUEST_EV 0

Per avviare l’esperimento basta eseguire il comando

dski_daemon -e kmalloc.dski

Dopo 10 secondi si otterra il file kmalloc.bin che andremo a filtrare col solito filtro dinarrazione definito come segue:

dtd_path = /usr/share/kusp/dtds

Page 33: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 32

input_file:kmalloc.bin # filenamebinary # file type# namespaces:/usr/src/2.6.12-RT-LIBERTOS/scripts/dski/mytest.ns

output_file:filtro1.xml # filenamexml # file type

filter utility.narrate {namespaces = [/usr/src/2.6.12-RT-LIBERTOS/scripts/dski/mytest.ns]

}

Salviamo come filtro1.filter ed eseguiamo

dstream_filter.py -c filtro1.filter

Si otterra in uscita il file narration.txt e soprattutto il file filtro1.xml di cui e riportatauna parte:

<ENTITY number="1" tag="0" time_stamp="31014398411854"clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="REQUEST_EV" family="KMALLOC_FAM" id="1344" ><EXTRA_DATA format="base64">IAEAAA==</EXTRA_DATA><EXTRA_DATA format="custom">Value = 288.000000

</EXTRA_DATA></EVENT></ENTITY><ENTITY number="2" tag="0" time_stamp="31014400330266"

clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="REQUEST_EV" family="KMALLOC_FAM" id="1344" ><EXTRA_DATA format="base64">GAAAAA==</EXTRA_DATA><EXTRA_DATA format="custom">Value = 24.000000

</EXTRA_DATA></EVENT></ENTITY><ENTITY number="3" tag="0" time_stamp="31014408096692"

Page 34: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 33

clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="REQUEST_EV" family="KMALLOC_FAM" id="1344" ><EXTRA_DATA format="base64">FAAAAA==</EXTRA_DATA><EXTRA_DATA format="custom">Value = 20.000000

</EXTRA_DATA></EVENT></ENTITY><ENTITY number="4" tag="0" time_stamp="31014408102180"

clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="REQUEST_EV" family="KMALLOC_FAM" id="1344" ><EXTRA_DATA format="base64">DAAAAA==</EXTRA_DATA><EXTRA_DATA format="custom">Value = 12.000000

Come si puo intuire gli extra dati corrispondono proprio al quantitativo di memoria che estato richiesto invocando la funzione kmalloc strumentata in precedenza.

2.4 Cenni sul funzionamento interno

Il framework di strumentazione DSKI-DSUI basa il proprio funzionamento sull’utilizzo di undispositivo virtuale a caratteri il cui scopo e quello di fornire un’interfaccia tra i punti distrumentazione inseriti nel kernel e le applicazioni d’utente che vogliono tracciare il flusso dicontrollo. In particolar modo il framework si occupa di tradurre le macro viste nelle sezioniprecedenti in opportune chiamate a funzioni che vanno a comunicare con questo dispositivovirtuale. Quindi il compito del dispositivo virtuale o datastream e da un lato memorizzaretemporaneamente le informazioni provenienti dal kernel, dall’altro fornirle al demone (o all’ap-plicazione) che si occupa di salvarle in un file binario per renderle disponibili al trattamentodi post–processing.

2.4.1 Il driver dstream

Il driver del dispositivo a caratteri e implementato nel file

<RootKernelLibeRTOS>/drivers/dstream/datastream.c

All’interno del file vi sono numerose funzioni che implementano anche altre funzionalita comeil logging diretto degli eventi in una socket, cosicche e possibile strumentare il kernel ancheda remoto, oppure in un file vero e proprio. Le informazioni tuttavia verranno, di default,loggate nel file /dev/dstream creabile attraverso il comando mknod /dev/dstream c 242 0.

Page 35: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 34

Le funzioni principali che ci interessano sono quelle di gestione del dispositivo a caratteri eprecisamente:

• ssize t datastream read(struct file * file, char *buffer, size t count,loff t * offset); Questa funzione viene richiamata quando si cerca di leggere dalfile /dev/dstream. In base al tipo di entita che deve essere letta essa invoca a suavolta la funzione active read implementata in datastream events.c locato ancora in<RootKernelLibeRTOS>/drivers/dstream.

• int datastream open(struct inode *inode, struct file *file); Questa funzio-ne viene richiamata nel momento in cui viene aperto il file /dev/dstream. Il suo scopoe quello di preparare le impostazioni iniziali per il file descriptor.

• int datastream close(struct inode *inode, struct file *file); Tale funzioneesegue le operazioni inverse di quella precedente e viene invocata ogni volta che ciascunaistanza del driver termina.

• int datastream ioctl(struct inode *inode, struct file *file, unsigned intcmd, unsigned long arg); Questa funzione rappresenta la principale interfaccia dicomunicazione tra il driver e l’esterno. Infatti attravero la sua chiamata e possibileimpostare una notevole quantita di parametri relativi al funzionamento e che sarannodescritti piu avanti.

Tutte le funzioni appena elencate vengono utilizzate dal kernel per registrare il device;infatti passando una struttura di tipo file operation alla funzione register chrdev e pos-sibile registrare il dispositivo. Nel caso dei datastream la struttura file operation e quellariportata di seguito:

static struct file_operations datastream_ops = {.read = datastream_read,.ioctl = datastream_ioctl,.open = datastream_open,.release = datastream_close,

};

2.4.2 Comunicazioni con il driver via ioctl

Il dispositivo a caratteri fornisce la funzione datastream ioctl() che permette di comunicareattraverso la system call ioctl() con il driver e impostare una serie di parametri. Tra iprincipali parametri che e possibile settare vi sono:

STREAM TYPE Definisce il tipo della sorgente del datastream: attiva nel caso degli eventi,passiva negli altri casi.

FD BUFFER SOCKET Imposta il file descriptor associato alla socket su cui si vogliono loggare idati contenuti nel buffer.

WRITE DATA TO SOCKET Richiede al driver di loggare i dati contenuti nel buffer in una socket.

Page 36: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 35

FILE DESC Imposta il file descriptor associato al file su cui si vogliono loggare i dati contenutinel buffer.

WRITE DATA TO FILE Richiede al driver di loggare i dati contenuti nel buffer in un file.

START DIRECT FILE LOG THREAD Richiede di iniziare il logging su un file.

ADD EVENT Segnala al driver che si e interessati al verificarsi di un evento. In questo modo sipuo selettivamente indicare quali eventi il framework deve loggare.

SET NUM OF EVENT Imposta il numero di eventi che verranno letti ogni volta che si esegue unalettura dal dispositivo.

START LOGGING Inizia il logging.

STOP LOGGING Termina esplicitamente il logging.

SET DURATION Imposta la durata di tempo durante il quale eseguire il logging (caso DSKI).

Gli altri parametri vengono utilizzati per l’uso dei contatori, degli istogrammi e peroperazioni concernenti problematiche tecniche che esulano dallo scopo della trattazione.

2.4.3 Breakpoints

Come visto nelle precedenti sezioni, la creazione di un breakpoint consiste nel definire unafamiglia e quindi degli eventi con opportuni identificativi simbolici. A un livello piu basso ilcharacter device lavora con degli identificativi numerici per cui il parser si fa carico di tradurreil file dello spazio dei nomi (*.ns) in una serie di macro che invocano delle funzioni che vannoa loggare coppie del tipo {ID entita, informazioni}. Il punto di incontro tra il character devicee la sorgente dei breakpoint risiede proprio nella corrispondenza realizzata dal parser.

Ad esempio nel caso degli eventi, supponiamo di aver creato una famiglia ESEMPIO FAMILYcon l’evento ESEMPIO EVENT; il parser creera la macro DSTRM EVENT ESEMPIO FAMILY che inrealta invoca la funzione log event. Tale funzione, che si trova sempre in datastream.c, hail seguente prototipo:

int log_event(int fam_id, int event_category, unsigned long set_number,int data_len, void *data, struct open_dstream *dstrm);

Il suo scopo e quello di memorizzare le informazioni relative ad un evento all’interno diun buffer e poi renderle disponibili attraverso una lettura sul dispositivo a caratteri. Si saranotato che l’operazione di scrittura sul device non e presente tra i campi di datastream opsma viene implementata proprio da questa funzione che rappresenta il punto di incontro tra ilkernel e il device.

2.4.4 Il demone dski daemon

Onde facilitare il recupero dei dati forniti dal character device la suite kusp mette a disposi-zione il demone dski daemon. Scopo di quest’ultimo e di leggere, con una frequenza definitadall’utente, i dati forniti dal driver e memorizzarli in un file binario. A tal proposito l’utentedeve fornire in ingresso al demone un file *.dski che definisca per l’appunto la durata delperiodo di osservazione nonche la frequenza di interrogazione del device.

Page 37: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 36

L’implementazione del demone e abbastanza semplice. Essa consiste semplicemente nelcomunicare col dispositivo attraverso la chiamata di sistema ioctl per impostare i parametridell’esperimento nonche nello sfruttare la semplice chiamata read per leggere le informazionidi interesse. Quindi come si puo osservare la filosofia alla base del framework DSKI di uti-lizzare le funzionalita indipendenti dall’architettura fornite dal sistema operativo linux rendela realizzazione e l’interfacciamento tra i vari livelli assai agevole. Infatti per poter ottenereinformazioni sui breackpoint e possibile utilizzare due semplici chiamate di sistema: ioctle read; inoltre questo meccanismo consente pure di realizzare funzionalita avanzate come ilprobing via rete e cio sicuramente e un punto di forza dell’intero framework.

2.5 Realizzazione di filtri

In questa sezione ci proponiamo di approfondire il meccanismo di utilizzo ma soprattutto dicreazione di un filtro da applicare ad un file binario contenente i dati grezzi da post-processare.A grandi linee possiamo analizzare il meccanismo di filtraggio da 2 punti di vista:

• implementazione di un filtro in python;

• creazione del file .filter per elencare i parametri su cui opera il filtro.

Sebbene risulti chiaro che non ha senso fare riferimento ad un filtro che non e statoimplementato, si procedera con un aproccio top down per far meglio cogliere il significato dicerti aspetti. Nelle sezioni seguenti prenderemo come esempio un filtro che faccia uso di unabase di dati. Il filtro che ci proponiamo di realizzare si pone come obiettivo quello di trasferirele varie informazioni relative agli eventi catturati (nome, famiglia, extra dato...) dentro undatabase in modo da poter, attraverso il linguaggio di interrogazione SQL, realizzare dellequery per ottenere informazioni ulteriori magari attraverso il raggruppamento.

2.5.1 Creazione di un file .filter

E’ stato gia detto nelle sezioni precedenti che l’utility filterconfig consente di creare inautomatico un file .filter che viene poi passato in ingresso al parser dstream filter.pyche a sua volta va a richiamare il codice python vero e proprio relativo al filtro passando tuttii dati necessari. Il file .filter consta fondamentalmente di 4 sezioni:

• file di input;

• file di output;

• dtd path;

• filtri23.

Nella sezione file di input e possibile elencare tutti i file di input al quale il filtro com-plessivo va applicato. I file di input possono essere o in formato binario o in formato xmle tale formato va esplicitamente indicato perche non si fa affidamento sull’estensione del file

23Ci sarebbe in realta anche la sezione “include” ma non viene analizzata perche non risulta necessaria peri nostri scopi

Page 38: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 37

stesso. E’ necessario ovviamente specificare il nome del file completo del relativo path24.Infine e necessario elencare i vari namespace file che forniscono l’indispensabile informazionesulle famiglie e sulle entita adoperate. Ad essere precisi i namespace file non sono semprenecessari; infatti nel momento in cui un file di input ha formato xml tali file sono superfluiperche un file xml puo essere ottenuto solo da una precedente operazione di filtraggio e quindii namespace file evidentemente sono stati gia forniti in una fase anteriore. In definitiva quindila sezione “file di input” (per la precisione input file) conterra tante terne del tipo

[path_file_input, formato, namespaces_files]

Al momento della chiamata del codice python queste terne vengono memorizzate in undizionario, una particolare struttura dati del linguaggio python che si puo paragonare ad unasorta di lista indicizzata attraverso chiavi di qualunque tipo (simile ad una memoria associa-tiva). Nel caso dei file di input la voce del dizionario puo essere, per l’appunto, “input files”.Prendendo come riferimento il filtro che ci siamo proposti di realizzare in precedenza, in talesezione sara sufficiente inserire i file binari da cui estrarre gli eventi da immagazzinare neldatabase. Per cui potremmo scrivere, all’inizio del file .filter, qualcosa come:

input_file:../events.bin # filenamebinary # file type/root/dski/test.ns # namespaces

Per la sezione file di output si puo ripetere lo stesso discorso fatto per la sezione dei filedi input con qualche differenza. Innanzitutto non e possibile specificare piu file di uscita inquanto il risultato del filtraggio deve essere diretto in un unico punto. Il file di uscita puoessere di tipo binario o xml nonche essere lo standard output del sistema (di default e infattiimpostato a sys.stdout). Si intuisce che un file xml, in quanto costituito da stringhe dicaratteri, e di dimensioni molto maggiori rispetto ad un semplice file binario ma in compensoe “interpretabile” direttamente dall’utente. Anche in questa sezione (output file), quindi,troveremo terne del tipo:

[path_file_output, formato, namespaces_files]

La voce del dizionario corrispondente in questo caso e proprio “output file”. Considerandoil filtro che intendiamo costruire, non sara necessario specificare un particolare file di uscitaperche il filtro deve solo trasportare i dati in un database quindi non produce un file di output.La cosa piu semplice da fare in tali casi e fornire come output lo standard output di defaultoppure eliminare la sezione di output. Naturalmente non sara necessario fornire neppure ilnamespace file quindi la sezione di output sara banalmente come segue:

output_file:sys.stdout # filename

24Tale percorso non deve essere necessaiamente assoluto ma puo anche essere relativo alla directory in cuiverra salvato il file .filter.

Page 39: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 38

La sezione dtd path contiene semplicemente l’informazione sul percorso in cui risiedonoi file .dtd utilizzati per la conversione in xml. L’infrastruttura mette a disposizione 2 file de-nominati composite stream.dtd e interval stream.dtd utilizzati rispettivamente quandosi ha a che fare con entita generiche e con intervalli. Naturalmente se il file di uscita non haformato xml tale sezione non va inserita perche tali file non sono necessari. A differenza delledue sezioni precedenti, in questo caso non abbiamo una terna ma un semplice elemento chespecifica il percorso verso i file .dtd:

dtd_path = [path_dtd_file]

La voce di dizionario corrispondente sara proprio “dtd path” e facendo riferimento alnostro filtro, in cui non c’e in uscita un file xml, la sezione risultera vuota.

La sezione finale, filtri, e di sicuro la piu importante perche contiene l’elenco dei filtri chevogliamo siano applicati, in pipeline, ai file di input specificati. Non e possibile descrivere inmaniera standard tale sezione in quanto ogni filtro differisce dagli altri. Possiamo pero direche per ogni filtro verranno elencati tutti i parametri di ingresso che gli consentono di agiresui file specificati nella sezione di input. Per cui all’interno di ogni filtro troveremo coppie deltipo:

parametro = valore

dove “parametro” specifica il nome del parametro d’ingresso25 e “valore” e il valore for-nito. Il filtro che trasferisce gli eventi nel database dovra ad esempio prendere le seguentiinformazioni:

• username: nome utente necessario per la connessione al database;

• password : password dell’utente;

• host : indirizzo della macchina che ospita il database;

• database: nome del database;

• tabella: nome della tabella in cui inserire gli eventi.

Per cui se precedentemente il nostro filtro python e stato chiamato “tomysql” ed e statoinserito tra quelli di generica utilita26, allora la sezione filtri potrebbe apparire come segue:

filter utility.tomysql {username = rootpassword = rootpasshost = localhostdatabase = dskitabella = Evento

}

25Si vedra che anche in tal caso si fa uso dei dizionari a livello di linguaggio python.26Nelle prossime sezioni si comprendera il significato di questa frase.

Page 40: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 39

Ricordiamo a questo punto che per ogni insieme di file di input e possibile applicare, inpipeline, piu filtri ma e anche possibile applicare la procedura di filtraggio ai risultati di unfiltraggio precedente. Per creare una pipeline sara sufficiente inserire nella sezione “filtri”l’elenco di tutti i filtri da utilizzare. Essi verranno applicati nell’ordine con cui sono elencatisecondo il meccanismo della “catena di montaggio” (pipeline appunto) ma alcuni tra i filtrigia disponibili debbono necessariamente essere posti all’inizio o alla fine di questa catena. Pereseguire un nuovo filtraggio, invece, sara sufficiente fornire come file di input del filtro i filedi output di un filtraggio precedente. La figura 2.11 mostra un esempio di questa duplicecatena.

Figura 2.11: Esempio di duplice filtraggio.

2.5.2 Implementazione di un filtro

Una volta analizzato il meccanismo di definizione di un filtro ad alto livello ci rimane dacapire come e possibile descrivere il comportamento del filtro vero e proprio. A tal scopo

Page 41: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 40

ricordiamo che i filtri disponibili gia nella piattaforma sono raggruppati in moduli, in base alloro significato. I moduli piu importanti sono i seguenti

• conversion: filtri usati per eseguire conversioni;

• expressive: filtri impiegati per tracciare statistiche relative agli interalli;

• interval : filtri da applicare nel caso in cui si usi l’entita intervallo;

• utility : filtri di utilita generica.

Ai fini della nostra discussione inquadreremo il filtro che impiega il database tra quelli digenerica utilita. Per comprendere il meccanismo di definizione di un filtro ricordiamo innanzi-tutto che ogni filtro deve essere realizzato attraverso il linguaggio Python che e un linguaggioorientato agli oggetti molto simile al Java per la sua natura di linguaggio interpretato. Il suopunto di forza, nella creazione di un filtro, sta essenzialmente nella presenza di numerosi tipidi dato strutturato primo fra tutti il “dizionario” ampiamente utilizzato per la memorizzazio-ne dei parametri di ingresso dei filtri. Cominciamo la nostra trattazione ricordando che ognifiltro in python e definito attraverso una classe a se stante e deve obbligatoriamente derivareda una classe definita nel modulo filter framework.py. Questo modulo contiene 4 classi:

• abstract filter: e la classe padre per eccellenza, da essa derivano tutte le altre classianche le classi del modulo filter framework.py;

• abstract start filter: e la classe da cui derivare i filtri che debbono essere postiall’inizio delle pipeline ossia quelli che non possono essere applicati a dei file di inputche risultano output di un altro filtraggio;

• abstract end filter: e la classe da cui derivare i filtri che debbono essere posti alla finedelle pipeline ossia quelli i cui file di output non possono subire un ulteriore filtraggio;

• abstract multi output filter: e la classe da cui derivare i filtri che debbono rediri-gere i loro output non in uno ma in piu punti.

E’ importante sottolineare che queste classi, benche denominate col prefisso abstract,non sono in realta classi astratte in quanto forniscono l’implementazione di vari metodi chepoi vengono ereditati dai filtri; il loro nome serve solo a suggerire che esse sono al vertice dellagerarchia dei filtri. Il nostro filtro non necessita di particolari vincoli quindi sara sufficiente chederivi dalla classe abstract filter. Nel costruttore di tale classe ( init ) vengono definitiuna variabile input e una output che verranno opportunamente caricate in fase di filtraggiocoi dati di input e i risultati dell’operazione di filtraggio rispettivamente. A tal scopo vengonoimplementati anche i metodi di open e close utilizzati per agire sui file veri e propri. Unavariabile assai interessante e quella denominata expected parameters; essa viene utilizzatanelle classi figlie (quindi nei filtri) per descrivere, attraverso un dizionario, i parametri diingresso che debbono essere forniti al filtro. Per questo motivo essa non viene inizializzatanella classe abstract filter ma deve avere un valore in ogni filtro derivato (a meno che iparametri di ingresso non siano assenti del tutto). Gli ulteriori metodi della classe servonoad eseguire operazioni solo in situazioni specifiche, come ad esempio il metodo do filteringusato solo nel caso di filtri all’inizio/fine della pipe per cui non vengono analizzati.

Page 42: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 41

Implementare un filtro quindi consiste nell’implementare una classe in linguaggio python.La prima cosa da fare e quella di scegliere il modulo in cui inserire il nuovo filtro. Abbiamodetto che il nostro filtro puo essere considerato un filtro di uso generico quindi lo porremonel modulo python utility filters.py. In tale modulo saranno gia presenti tutti gli altrifiltri di tipo utility percio ci posizioneremo alla fine dello stesso. Definiamo quindi la classein python:

class tomysql_filter(filter_framework.abstract_filter)

cosı facendo, l’ulitity filterconfig presentera il nuovo filtro nell’elenco denominandoloutility.tomysql. I metodi della classe sono essenzialmente 3:

1. def init (self, parameters, input=None, output=None)usato per inizializzare la variabile expected parameters con la descrizione dei parame-tri e stabilire la connessione con il database;

2. def process(self, entity)e il metodo fondamentale, serve a trasferire i dati nel database;

3. def close(self)e usato per chiudere la connessione col database.

Benche stiamo facendo riferimento ad un caso particolare, i metodi di inizializzazione e diprocessazione sono sicuramente presenti in qualunque filtro. Notiamo che tutti i metodi pren-dono in ingresso il parametro self che e molto simile al puntatore this del C++ e serve perriferirsi alla classe nonche alle variabili membro (self.nome var). Il metodo fondamentaleprocess deve prendere come argomento il parametro entity ossia l’entita (evento, contato-re...) che viene memorizzata nel file binario in seguito ad un esperimento. Naturalmente ogniesperimento produce tantissime entita (una per ogni evento generato, una per ogni contatoreutilizzato...) quindi il metodo process viene iterativamente applicato a tutte le entita chevengono incontrate nel file che contiene i dati grezzi a differenza dei metodi di init eclose richiamati una sola volta rispettivamente all’inizio e alla fine della fase di filtraggio.

A questo punto ci resta da esaminare come vengono realizzati i singoli metodi. Nel metododi inizializzazione (costruttore) bisogna innanzitutto invocare il costruttore della classe padre

filter_framework.abstract_filter.__init__(self, _input, _output)

quindi definiremo una variabile membro per ogni possibile parametro di ingresso secondola sintassi:

self.nomevar = parameters["nomevariabile"]

Questa riga inizializza il valore della variabile membro nomevar col valore del parametrodi ingresso chiamato “nomevariabile”. Si noti come l’indicizzazione dei parametri avvieneattraverso una stringa di caratteri perche viene utilizzato un dizionario e non un semplicearray. Nel nostro caso ad esempio avremo bisogno di definire una variabile per inserire ilnome utente e quindi scriveremo

self.username = parameters["username"]

Page 43: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 42

Naturalmente finora non abbiamo precisato nessuna informazione relativamente alla varia-bile, neppure il tipo. Tutte le informazioni debbono essere inserite inizializzando la variabileexpected parameters. Tale variabile e un dizionario le cui voci sono a loro volta dei dizio-nari. Per ogni parametro troveremo una voce nel dizionario expected paramerers quindi nelnostro caso troveremo la voce username. Ma ogni voce a sua volta e un dizionario costitutitoda almeno 4 voci. Infatti per ogni parametro di ingresso e possibile specificare 4 informazionifondamentali:

1. type: specifica il tipo del parametro e puo assumere i seguenti valori definiti nel moduloconstants.py:

• PARAM INT: numero intero;

• PARAM LONG numero intero long;

• PARAM REAL numero reale;

• PARAM STRING stringa di caratteri;

• PARAM LIST lista27 di valori;

• PARAM BOOL booleano.

2. order : e un numero intero per specificare l’ordine con cui viene richiesto il parametro;

3. doc: una breve documentazione che comparira nella finestra del filtro di filterconfig;

4. default : valore di default.

Nel nostro esempio la username e una stringa e quindi potremo scrivere:

expected_parameters = {"username":{"type":const().PARAM_STRING,

"order":10,"doc":"Nome Utente database","default":"root"}

}

Una volta descritti i parametri di ingresso non resta che inizializzare eventuali ulteriorivariabili che verranno usate nel metodo di processazione. Nel nostro caso ad esempio e ne-cessario stabilire una connessione al database quindi e necessaria una variabile per mantenereaperta la connessione e una per mantenere il cursore agli elementi inseriti nella tabella28.

Per quanto concerne il metodo di processazione esso costituisce il core del filtro e in essone viene definito il comportamento. Ogni filtro naturalmente lo implementera secondo gliscopi per cui e realizzato ma vale la pena ricordare che sull’oggetto entity, passato in ingresso,il modulo ds entities.py mette a disposizione coppie di metodi del tipo “set” e “get” persettare o leggere informazioni riguardo all’entita. Le informazioni che vengono inserite neidati grezzi in seguito all’esperimento, per una entita semplice come un evento, sono elencate

27La lista e un tipo molto simile al dizionario in quanto per ogni elemento della lista bisogna specificare iltipo, la documentazione, il valore di default...

28A monte di tutto cio si suppone ovviamente di aver creato un opportuno database con almeno una tabellaper inserire le informazioni nonche di aver importato nel modulo in cui definiamo la classe del filtro il moduloche offre i metodi per la connessione al database stesso.

Page 44: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 2. DESCRIZIONE DEL TOOL DSKI/DSUI 43

Name Nome dell’evento definito nel namespace fileFamily Famiglia di cui l’evento fa parte, anche essa definita nel namespace fileNumber Numero progressivo dell’entita catturataTimeStamp Numero di jiffies all’istante di logging ossia il numero dei tick del

processore tra l’istante di boot e la generazione dell’eventoTag E’ una sorta di identificativo il cui valore dipende dal parametro cor-

rispondente indicato attraverso il punto di strumentazione (e semprepositivo) e che serve a discriminare eventi

ExtraData Dato extra il cui valore dipende dal parametro corrispondente indicatoattraverso il punto di strumentazione e il cui formato e precisato dallafunzione di print nel namespace file

Tabella 2.1: Lista delle informazioni loggate relative ad un evento.

nella tabella 2.1. Nel nostro caso dobbiamo semplicemente usare i metodi di get per leggerele informazioni dalle entita e trasferirle nel database quindi nel metodo process vengonoinvocati, sull’oggetto entity, i metodi getName(), getFamily(), getTag() etc.

Nel metodo di close, che non sempre sara necessario, vengono eseguite le eventuali opera-zioni finali relative alla processazione cioe quelle che non possono essere specificate nel metodoprocess perche verrebbero ripetute per ogni entita. Nel nostro caso le uniche operazioni ri-guardano la dereferenziazione del cursore e la chiusura della connessione. Per esaminare ilcodice completo di un filtro fare riferimento alla sezione C.

Una volta che il filtro e stato realizzato, bisogna compiere un’ultima operazione per ren-derlo visibile all’utility filterconfig. Abbiamo detto che i filtri vanno implementati in unodei moduli elencati all’inizio di questa sezione; facendo riferimento alla directory in cui einstallata la suite kusp, tali moduli si trovano nel percorso

<KUSP>/src/datastreams/build/lib/datastreams/postprocess/filters/builtin

Per rendere visibile il nuovo filtro bisonera rieseguire i comandi descritti nella sezione A eprecisamente:

makemake install

Naturalmente i comandi non devono compilare i sorgenti, data la natura del linguaggioPython, ma sposteranno semplicemente i moduli modificati in opportune directory del siste-ma. Cosı facendo l’utility filterconfig rilevera il nuovo filtro automaticamente al prossimoriavvio e una volta eseguito il parsing della variabile expected parameters mostrera, dopoaver aggiunto il filtro alla pipeline, una finestra di dialogo in cui inserire i parametri di ingressonecessari affinche siano processati i dati.

Page 45: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Capitolo 3

Caso di studio

Nel capitolo precedente sono state esaminate le caratteristiche e le potenzialita del frameworkdi strumentazione DSKI; nel lavoro di tirocinio svolto sono stati analizzati anche altri tooldi probing del kernel, in particolare l’interesse e ricaduto sulla coppia KProbes/SystemTAP.Questi due framework sono complementari, in quanto il secondo sfrutta le funzionalita dibasso livello offerte dal primo; quello di cui ci vogliamo occupare in questo capitolo e innan-zitutto di confrontare a priori i tool, nel senso di effettuarne un confronto a partire dallecaratteristiche di base, dopodiche impiegarli in un esperimento pratico ed analizzarne i ri-sultati, evidenziando cosı i vantaggi e gli svantaggi dell’impiego di ciascuno strumento. Peravere un’analisi approfondita del framework KProbes/SystemTAP fare riferimento a [TESIDI PAOLO].

3.1 Confronto DSKI – KProbes/SystemTAP

Come si puo evincere dal capitolo precedente, DSKI fornisce uno strumento di probing to-talmente indipendente dall’architettura della macchina sottostante, quindi si tratta di unframework di alto livello; utilizzando congiuntamente un dispositivo a caratteri virtuale (fa-re riferimento alla sezione 2.4) ed un demone eseguito in background e in grado di reperireinformazioni sui meccanismi interni del kernel. KProbes/SystemTAP, dall’altra parte, sfrut-ta un approccio di basso livello, adoperando le debugging facilities fornite dall’architetturasottostante, per fornire uno strumento di probing dinamico. Entrambi gli approcci dei dueframework hanno dei pro e dei contro; lo scopo che ci prefiggiamo in questa sede e di con-frontarli sulla base delle loro caratteristiche fondamentali, quindi una sorta di confronto apriori. In particolare, sebbene KProbes/SystemTAP possano essere considerati come un uni-co strumento, in questa sede li considereremo come tool separati, in quanto KProbes e unostrumento di basso livello che dipende dall’architettura, SystemTAP invece poggia su KPro-bes e fornisce funzionalita di alto livello per cui puo essere adoperato alla stessa maniera suarchitetture differenti purche sia fornito lo strato di basso livello, KProbes, per l’architetturain questione.

Di seguito sono riportate le considerazioni per i vari tool secondo varie basi di confronto:

Procedimento di strumentazione

• KProbes/JProbes L’inserimento di punti di strumentazione comporta sia la cono-scenza del linguaggio C, sia la capacita di creare moduli del kernel.

44

Armando Migliaccio
Note
evita di riprendere concetti già esposti. Il pagrafo può iniziare tranquillamente dicendo DSKI fornisce uno strumento bla bla...
Page 46: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 45

• SystemTAP Non e necessaria alcuna conoscenza del linguaggio C o capacita di crearemoduli. E’ necessaria pero la conoscenza del linguaggio di scripting.

• DSKI E’ necessaria una parziale conoscienza del C. Procedimento di strumentazionesupportato da utility grafiche.

Dipendenza dall’architettura

• KProbes/JProbes KProbes e Jprobes dipendono altamente dall’architettura sotto-stante. In particolar modo sfruttano le funzionalita fornite dall’architettura per lagestione degli interrupt nonche per il supporto del debugging. Tuttavia fornisconoun’interfaccia univoca a livello di linguaggio C.

• SystemTAP Completamente indipendente dall’architettura a livello del linguaggio discripting, anche se basa le proprie funzionalita sull’utilizzo di KProbes e JProbes.

• DSKI Completamente indipendente dall’architettura. Infatti fa utilizzo esclusivamen-te di funzionalita di alto livello fornite dal kernel (in particolar modo del filesystemvirtuale).

Inserimento di Breakpoints

• KProbes/JProbes Presuppone la conoscenza esatta dell’indirizzo del punto da stru-mentare (entry point di funzione o istruzione singola). Ovviamente tale informazionevaria a seconda dell’immagine binaria del kernel.

• SystemTAP Non presuppone la conoscenza esatta di un indirizzo perche si basa sulleinformazioni simboliche di debug fornite dal processo di compilazione del kernel.

• DSKI Presuppone l’inserimento diretto nel codice sorgente dei punti di strumentazione.

Postprocessing

• KProbes/JProbes Non fornisce alcun supporto al postprocessing dei dati di strumen-tazione. Il tutto e a cura dell’utente.

• SystemTAP Fornisce uno scarso supporto al trattamento dei dati raccolti permettendoesclusivamente di tracciare istogrammi realizzati in modo elementare.

• DSKI Fornisce un supporto molto completo al trattamento dei dati grazie alla suite(KUSP) che permette di effettuare elaborazioni sequenziali sui dati, permettendo filtrag-gio e formattazione grafica degli stessi. Inoltre permette l’estensione dei meccanismi dipostprocessing attraverso l’impiego del linguaggio Python.

Agilita d’uso

• KProbes/JProbes Fornisce un’agilita d’uso medio-elevata, dal momento che non ri-chiede ne la compilazione del kernel (in quanto e in grado di strumentare dinamicamentel’immagine binaria del kernel) ne le informazioni simboliche di debug (in quanto nonstrettamente necessarie). L’utente dovra, tuttavia, costruire moduli che andranno op-portunamente caricati e scaricati nonche registrare e cancellare esplicitamente nel codicedel modulo i punti di strumentazione e fornire delle opportune funzioni di handling.

Armando Migliaccio
Note
conoscenza...
Page 47: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 46

• SystemTAP Fornisce un’agilita alta, in quanto, basando il proprio funzionamento suKProbes e Jprobe, e necessario fornire esclusivamente il file di scripting che descrive leoperazioni da effettuare nel momento in cui il flusso di controllo attraversa i breakpoint.Tutte le problematiche sono nascoste dall’utility stap che si occupa della traduzionedello script, nonche della creazione di un modulo di probing che provvedera automa-ticamente a caricare e scaricare. Quindi non e necessario ricompilare il kernel, anchese sono necessarie comunque le informazioni simboliche di debug che aumentano ladimensione finale dell’immagine binaria del kernel stesso.

• DSKI Sebbene fornisca un supporto molto avanzato al postprocessing, la sua agilitad’uso non e molto elevata. Infatti presuppone, per l’inserimento dei breakpoints, lamodifica del codice sorgente stesso (che potrebbe tradursi in effetti collaterali impredi-cibili), nonche la ricompilazione del kernel stesso ogni volta che risulti necessario inserireun nuovo breakpoint o eliminarne uno.

Risoluzione di probing

• KProbes/JProbes Fornisce una risoluzione di probing limitata all’entry point di unafunzione.

• SystemTAP La risoluzione di probing e illimitata. Grazie alle informazioni di debugessa puo arrivare perfino alla singola riga di un file sorgente.

• DSKI C’e una risoluzione molto elevata, anche in questo caso e possibile monitorareun qualunque punto del codice sorgente (ammesso che faccia parte di una funzione).

Visibilita dei dati

• KProbes/JProbes KProbes non e in grado di fare assunzioni sulle variabili localie sui parametri passati ad una funzione quindi non e in grado di reperire tali dati(tuttavia con una conoscenza di basso livello ed impiegando il linguaggio assembly epossibile ricavare tali informazioni). Jprobes e in grado di strumentare l’entry point dellefunzioni, potendo interpretare i parametri ad esse passati; non e in grado, comunque,di strumentare le variabili locali.

• SystemTAP Considerando che SystemTAP fa uso delle informazioni di Debug delkernel, e in grado di accedere a qualunque variabile o struttura dati.

• DSKI E’ in grado di accedere al contenuto delle variabili locali di cui bisogna specificarela dimensione e l’indirizzo nel momento in cui si inserisce un Breakpoint.

Supporto

• KProbes/JProbes Essendo parte integrante del kernel dalla versione 2.6 e facilereperire documenti ufficiali e notizie relative al tool.

• SystemTAP Esso e stato sviluppato da un gruppo di societa e non e integrato nelkernel standard. Non e difficile comunque ritovare informazioni sul tool ma esso eancora in fase sperimentale.

Page 48: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 47

• DSKI Non e integrato nel kernel standard ed e stato sviluppato alla Kansas Univer-sity. Fatta eccezione per pochi documenti inclusi nella suite KUSP e difficile trovareinformazioni a riguardo; inoltre anche DSKI e in fase sperimentale e presenta ancoraqualche evidente problema riguardo alla perdita di eventi.

3.2 Workloads

Abbiamo confrontato nella sezione precedente i due tool di probing analizzati nel corso dellavoro di tirocinio. Adesso vogliamo impiegare i due tool in un caso reale ossia utilizzarliper ottenere dati quantitativi che permettano di analizzare il comportamento del kernel delsistema operativo, o di un suo sottosistema, in presenza di un determinato stimolo in ingresso.In questa sede, oltre ai risultati numerici, quello che risulta essere di particolare importanza el’approccio metodologico adoperato vale a dire l’analisi del comportamento del kernel sotto-posto ad uno stress scelto a priori e quale sia la validita, nonche i limiti di questa tecnica. Insostanza, non potendo prevedere a priori la situazione in cui il sistema andra ad operare, sisimula un carico tipico per lo stesso, per cercare di diagnosticare situazioni anomale e effetticollaterali imprevisti in fase di progettazione. Il problema e che bisognerebbe stabilire, datal’enorme eterogeneita dei workload a cui un sistema puo essere sottoposto, quale sia il wor-kload ideale, ossia che copra tutti i possibili carichi presentabili; per tal motivo l’approccioadottato e stato quello di suddividere i workload esistenti in tre classi: CPU, I/O e MEMORYbound cosı definiti:

CPU bound Questa situazione si riferisce ad una condizione in cui il tempo per completareuna computazione e determinato principalmente dalla velocita dell’Unita Centrale. Ciosignifica che la computazione mantiene l’utilizzo del processore molto alto e che quest’ul-timo non sta spendendo molto tempo in attesa di interrupt come nel caso in cui si debbaattendere la terminazione di un’operazione di IO. In tal caso un programma che e CPUbound puo aumentare le proprie prestazioni soltanto se viene impiegato un algoritmomigliore oppure se si utilizza un processore con una velocita di calcolo superiore.

I/O bound In tal caso ci si riferisce ad una condizione in cui il tempo per completare unacomputazione e determinato principalmente dagli intervalli di tempo spesi in attesa chele operazioni di IO vengano completate. Esempi di questo tipo sono processi che devonoleggere/scrivere dati dal disco o da una socket; in tal caso le prestazioni dipendono dasvariati fattori (tempo di accesso al disco, algoritmo di scheduling del disco etc.) e nonesistono soluzioni generalmente valide per eliminare il problema dal momento che unprocesso non puo intervenire su tali fattori.

MEMORY bound In questo caso ci si riferisce ad una situazione in cui i fattori primariche limitano la velocita e il tempo di esecuzione di un processo sono principalmentela velocita di accesso alla memoria e la quantita a disposizione. Per questo motivoquando la CPU deve elaborare grandi quantita di dati, avendo un limite sulla capacitadella memoria e sulla sua velocita, vengono eseguite molte operazioni di swapping suldisco, per cui il tempo di esecuzione viene limitato da questi tempi morti in cui non vie lavoro utile. Per migliorare le prestazioni in tali situazioni bisogna intervenire nelletecniche che il processo utilizza nel gestire i propri dati, come ad esempio accesso aidati di una matrice memorizzata per righe su di un’architettura che usa la paginazione;

Page 49: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 48

generalmente intervengono molti fattori non controllabili dal processo come la latenzadi accesso alla memoria o al disco, oppure l’algoritmo di gestione della memoria delsistema operativo.

A partire dai risultati ottenuti stressando il kernel con questi carichi si e cercato di stabilirese l’esperimento fosse ripetibile, ossia se possedesse caratteristiche di stazionarieta; in tal casosi potrebbe costruire un workload come fusione dei tre presentati sopra. Naturalmente unapproccio alternativo sarebbe quello di utilizzare un carico dalle caratteristiche completamentecasuali che, non rientrando in degli schemi prefissati, puo in qualche modo permettere discovare rapporti causa–effetto impredicibili e di intervenire su di essi per migliorare la stabilitadel sistema.

In particolare i workload adoperati sono stati UnixBench per il caso CPU bound eiozone per il caso IO bound. Per quanto riguarda invece il caso MEMORY bound si e optatiper la realizzazione di un workload appositamente creato per la macchina su cui sono statieffettuati i test.

3.2.1 UnixBench

UnixBench e una suite di benchmarks modulari che e possibile combinare tra di loro a secondadelle esigenze; tali moduli sono raggruppati in gruppi logici definiti come di seguito:

arithmetic insieme di benchmark aritmetici che simulano il comportamento di applicazioniscientifiche tipiche; in particolare sono forniti il benchmark di Whetstone per il calcolodelle prestazioni delle operazioni in virgola mobile del processore, nonche una serie diworkload per ogni tipo di dato numerico (int, long, double etc.).

system insieme di benchmark per testare l’overhead delle operazioni di sistema (overhead dichiamata a system call, pipe throughput, overhead di creazione processi etc.).

misc insieme di benchmark che simulano il comportamento di applicazioni non numerichecome ad esempio compilazione C, chiamate ricorsive e operazioni su stinghe (simulandocosı il comportamento di compilatori, editor testuali etc.).

Dal momento che UnixBench e stato impiegato per generare un carico di tipo CPU bound estato scelto il modulo arithmetic. Tra i vari sottomoduli l’attenzione e ricaduta precisamentesui moduli Whetstone e Dhrystone descritti di seguito.

Whetstone e Dhrystone

Il benchmark Whetstone nasce con lo scopo di misurare le performance di calcolo floatingpoint di un processore; esso cerca di fornire una valutazione quantitativa della velocita dicalcolo della macchina in termini di KWIPS, (KiloWhetstone Per Seconds, ossia migliaiadi cicli Whetstone per secondo) mentre alcune versioni piu avanzate autocalibranti offronorisultati in termini di MOPS (Millions of OPerations per Seconds). Le caratteristiche che locontraddistinguono sono:

1. contiene un’alta percentuale di dati e istruzioni floating point;

2. circa il 50% dell’esecuzione e spesa in funzioni matematiche li libreria (sin(), cos(),tan() etc.);

Armando Migliaccio
Note
abbiamo optato...
Page 50: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 49

3. i cilci impiegati sono molto brevi in tal modo processori dotati di un Instruction cachevedono aumentare le loro prestazioni significativamente;

4. i dati sono globali, in maniera tale che i processori RISC non possano avvantaggiarsidella presenza di un maggiore numero di registri general purpose per la gestione divariabili locali.

Il benchmark Dhrystone sfrutta la stessa idea di base del benchmark Whetstone1, cercandopero di stimare le prestazioni del processore in presenza di carichi che eseguono computazioninon numeriche. La sua attenzione e rivolta soprattutto ad operazioni intere o su stringhe,cercando di simulare il carico tipico fornito da applicazioni come word processors, compilatorietc. Esso e progettato in maniera tale da poter confrontare anche l’output generato da piucompilatori per la stessa macchina, potendo cosı confrontare le ottimizzazioni introdotte infase di compilazione da ciascuno di essi. Le sue caratteristiche fondamentali sono di seguitoelencate:

1. non contiene alcuna operazione floating point;

2. una percentuale considerabile del tempo di esecuzione e speso su operazioni che lavoranosu stringhe;

3. i cicli impiegati non sono, come in Whetstone, molto brevi ma studiati in maniera taleda generare cache miss. In questo modo vengono stimate le performance con cui ilprocessore gestisce il codice e i dati, oppure come il compilatore riesce ad ottimizzare ilcodice;

4. c’e solo una piccola percentuale di variabili globali, cosı i processori RISC ottengonoun notevole miglioramento delle prestazioni dal momento che gestiscono in modo piuefficiente i dati locali (a differenza di prima).

3.2.2 IOzone

IOzone e un insieme di benchmark per calcolare le prestazioni del sottosistema di gestione diIO di Linux. In particolare esso e utile per effettuare analisi su una vasta gamma di operazionitipiche del filesystem tra cui:

write tale test misura le performance di scrittura di un nuovo file. Quando un nuovo fileviene scritto necessitano di essere memorizzati non solo i dati ma anche le informazioniaggiuntive per tenere traccia di dove gli stessi siano locati sul supporto. Queste infor-mazioni aggiuntive sono chiamate metadati e consistono di informazioni di directory, dispazio allocato e altri dati associabili al file ma che non fanno parte del suo contenu-to. E’ normale quindi che le performance di una write iniziale siano piu basse di unare–write proprio a causa di questo overhead.

re–write questo test misura le performance di scrittura su di un file gia esistente. Quandosi scrive su un file pre–esistente il lavoro richiesto e minore dal momento che i metadatisono gia presenti. E’ normale che le performance in tal caso migliorino rispetto al casodescritto prima.

1Il nome stesso deriva da un gioco di parole basato sul nome del benchmark Whetstone.

Page 51: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 50

read questo test misura le performance di lettura di un file.

re–read tale test misura le performance di lettura di un file recentemente letto. Solitamentele prestazioni sono migliori rispetto al caso precedente dal momento che spesso il sistemaoperativo mantiene una cache dei dati recentemente letti.

random read questo test misura le performances di accesso casuale in lettura ad un file. Leperformances in tal caso dipendono da svariati fattori come la dimensione della cachedel sistema operativo, la latenza di seek etc.

random write questo test misura le performance di accesso casuale in scrittura ad un file.

backwards read questo test misura le performance nel leggere un file all’indietro. Nono-stante vi siano molti sistemi operativi che hanno delle caratteristiche speciali che con-sentono di leggere un file in avanti molto rapidamente, vi sono pochi sistemi operativiche riconoscono e migliorano le perstazioni di una lettura di un file all’indietro.

mmap molti sistemi operativi supportano l’uso della mmap() per mappare un file nello spazioindirizzi dell’utente. Una volta eseguita la mappatura una modifica di un dato in questaarea di memoria si traduce in una modifica sul file. Questo e utile se l’applicazionedesidera utilizzare un file come segmenti di memoria. La coerenza tra i dati contenutiin memoria e quelli memorizzati sul disco puo essere gestita in maniera sincrona oasincrona e scopo del benchmark e di calcolare le performance di questo meccanismo.

3.2.3 Workload MEMORY bound

Per quanto riguarda il caso MEMORY bound si e scelto di realizzare un workload su misuraper la macchina dell’esperimento; dal momento che il nostro scopo e stressare il sottosistemadi gestione della memoria del sistema operativo si e realizzata un’applicazione che richiedememoria ad oltranza finche il sistema operativo non e costretto ad impiegare l’area di swapquindi si rilascia la memoria. Tale operazione viene eseguita ciclicamente e di seguito siriporta l’implementazione del workload:

#include <stdio.h>#include <stdlib.h>

int main() {printf("Programma Memory Bound\n");

int *mem_area[560000];int allocated;int failed;int numofcycles;numofcycles = 0;int i;int j, k;

for(;;) {// Fase di allocazione

Page 52: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 51

printf("Allocazione in corso\n");allocated = 0;failed = 0;while((allocated < 560000) && (failed == 0)) {

mem_area[allocated] = (int *) malloc(sizeof(int) * 1024);if(mem_area[allocated] == NULL) {

failed = 1;printf("Fallita un’allocazione\n");

} else {allocated++;

}}

//Ciclo di pausafor(j = 0; j < 4000000; j++)

for(k = 0; k < 40; k++);

// Fase di deallocazioneprintf("Deallocazione in corso\n");for(i = allocated; i == -1; i--) {

free(mem_area[i]);}

}}

Come si puo notare, il workload e abbastanza sintetico e lineare. Esso opera in due fasi

• nella prima fase il programma richiede al sistema operativo, attraverso la funzione dilibreria C malloc()2, un quantitativo di memoria pari a 2.1 GB (560000 * 32 * 1024bit). Considerando che la macchina stressata possiede 2 GB di memoria fisica, cio vuoldire che il sistema operativo cominciera ad usare la memoria di swap;

• nella seconda fase l’applicazione libera totalmente la memoria allocata e tutto ricomin-cia.

L’ultima cosa da annotare e che tra l’allocazione e la deallocazione e previsto un ciclo dipausa per ridurre la frequenza delle richieste di memoria e dare all’utente la possibilita diaccorgersi delle richieste fatte3.

3.3 Scopo degli esperimenti

Nelle sezioni precedenti ci siamo proposti di adoperare dei particolari workloads per stressareil kernel del sistema operativo; in particolare il nostro interesse ricade sull’interfaccia trasistema operativo e processi utente, ossia l’insieme di system call fornite. Ricordiamo che

2Si ricordi che la malloc() alla fine si traduce nella chiamata alla system call brk().3Si noti che la pausa non viene realizzata con la chiamata a system call sleep() onde evitare di inquinare

i risultati sperimentali.

Armando Migliaccio
Note
notare
Page 53: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 52

una system call, infatti, costituisce il punto di ingresso per i programmi d’utente che voglionoottenere un servizio demandandolo al sistema operativo; per tal motivo la strumentazionedelle system call fornisce indicazioni utili sul funzionamento del sistema operativo stesso.In particolar modo e utile osservare ad esempio la frequenza con cui vengono chiamate aseconda del workload applicato (I/O bound, CPU bound, MEMORY bound) nonche l’esitodella chiamata (che dipende ovviamente dalla semantica della system call). Tali dati possonoessere utilizzati per diagnosticare un problema di stabilita, soprattutto perche Linux e unsistema operativo open source e vi e bisogno di maggiori garanzie nel momento in cui vengautilizzato in applicazioni critiche.

Il primo passo in questa direzione consiste nel capire come il S.O. gestisce le system call, inmaniera tale da trovare la modalita ottima con cui utilizzare i due tool studiati. Nello specificovediamo come le chiamate di sistema vengono gestite da un kernel Linux su piattaforma x86.

3.3.1 Sottosistema di gestione delle System Call in Linux

Un processo utente per completare la propria esecuzione ha bisogno di risorse tra cui memoria,processore, spazio sul disco etc. Nella realizzazione di un programma e teoricamente necessa-rio (o quantomeno e utile) conoscere i dettagli architetturali del sistema su cui l’applicazionesara eseguita; se pero i programmatori si dovessero preoccupare dei “dettagli” la complessitarealizzativa dell’applicazione sarebbe talmente elevata da impedire un facile e veloce svilup-po della stessa. Per questo motivo il sistema operativo nasconde la complessita, nonchel’eterogeneita, del sistema sottostante fornendo una serie di servizi al livello applicativo. Inquesto modo l’applicazione, sfruttando i servizi messi a disposizione, vedra un’astrazione dellamacchina sottostante.

Le system call nascono proprio per questo scopo; esse rappresentano il punto di contattofra il livello applicativo e il sistema operativo che a sua volta svolgera il compito richiestoridando poi il controllo all’applicazione. In parole povere le system call svolgono una serie dioperazioni in modalita supervisore per conto di un processo che funziona in modalita utente eche quindi non potra mai eseguire istruzioni privilegiate. E’ necessario percio che l’architetturadella macchina sottostante fornisca un meccanismo attraverso il quale il processo in questionepossa richiamare segmenti di codice del sistema operativo. La tecnica adoperata dalla maggiorparte dei sistemi e quella di impiegare le interruzioni software o traps. Sull’architettura x86e possibile registrare una ISR che risponda ad un vettore di interruzione passando quindidalla modalita utente alla modalita supervisore e quindi in effetti passando da un task utentead uno del sistema operativo; proprio questo e l’approccio che si adopera anche in Linuxsull’architettura x86.

3.3.2 ISR come handler di System Calls

Il meccanismo di gestione di una system call in Linux presuppone innanzitutto che si siaregistrata una ISR per l’Interrupt 0x80; quando un processo vuole invocare una system call,memorizza l’identificativo numerico della stessa nel registro EAX del processore. Questo IDfa parte di una tabella memorizzata nel file sorgente asm/unistd.h. I parametri della systemcall vengono poi salvati nei registri in ordine EBX, ECX, EDX, ESI, EDI; se questi registrinon dovessero bastare viene utilizzato anche lo stack. Questa tecnica viene utilizzata pervelocizzare il processo di chiamata dal momento che l’acceso ai registri e piu volece rispettoad uno in memoria. A questo punto il processo effettua una Software Interrupt attraverso

Armando Migliaccio
Note
un sistema open source non necessarimanete è peggiore di altri commerciali.
Armando Migliaccio
Note
come motivazione non è molto chiara. Diciamo che l'obiettivo della ricerca è stabilire l'affidabilità del kernel linux. Un kernel offre i suoi servizi attraverso le SVC. Dunque tale affidabilità è determinata direttamente dalla misura in cui le SVC falliscono, ovvero la misura secondo cui una SVC, stimolata con parametri di input corretti e non, soddisfa il comportamento atteso. Questo non è stato il vostro obiettivo della ricerca, tuttavia i passi preliminari sono: 1) isolare le SVC più critiche (cioè quelle stimolate maggiormente) 2) individuare come le SVC rispondono a sollecitazioni di un workload, ovvero ad un programma che simula il comportamento di uno corretto.
Page 54: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 53

l’esecuzione dell’istruzione INT 80h e il flusso di controllo passa all’ISR registrata per il vettore80 memorizzata nel file entry.S di cui si mostra la sezione interessata:

ENTRY(system_call)pushl %eax # save orig_eaxSAVE_ALL

#ifdef CONFIG_LATENCY_TRACEpushl %edx; pushl %ecx; pushl %ebx; pushl %eaxcall sys_callpopl %eax; popl %ebx; popl %ecx; popl %edx

#endifGET_THREAD_INFO(%ebp)

# system call tracing in operation/* Note, _TIF_SECCOMP is bit number 8, and so it needs testw and not testb */testw $(_TIF_SYSCALL_TRACE|_TIF_SYSCALL_AUDIT|_TIF_SECCOMP),TI_flags(%ebp)jnz syscall_trace_entrycmpl $(nr_syscalls), %eaxjae syscall_badsys

syscall_call:call *sys_call_table(,%eax,4)movl %eax,EAX(%esp) # store the return value

syscall_exit:cli # make sure we don’t miss an interrupt

# setting need_resched or sigpending# between sampling and the iret

movl TI_flags(%ebp), %ecxtestw $_TIF_ALLWORK_MASK, %cx # current->workjne syscall_exit_work

restore_all:movl EFLAGS(%esp), %eax # mix EFLAGS, SS and CS$

Come e possibile osservare l’handler system call per chiamare la system call effettiva uti-lizza l’indirizzo di base della tabella delle system call (puntato dal puntatore sys call table)a cui aggiunge lo spiazzamento ottenuto dal prodotto di EAX per un fattore 4 dal momentoche gli indirizzi sono a 32 bit (4 byte). In tal modo ottiene l’indirizzo effettivo dell’entry dellasystem call a cui cede il controllo (call). La system call viene eseguita e, come da convenzio-ne per le chiamate delle funzioni C-Assembly per l’architettura x86, il valore di ritorno vienememorizzato in EAX se si tratta di un valore rappresentabile entro 32 bit4 oppure se si trattadi una struttura dati EAX contiene un puntatore al valore. Il controllo viene quindi restituitoal processo che ha richiesto il servizio.

3.3.3 Contesto degli esperimenti

Una volta discusso il meccanismo di gestione delle system call non rimane che preparare edeseguire gli esperimenti utilizzando i tool presi in considerazione. Gli esperimenti eseguiti

4Solitamente le system call ritornano un long che in effetti e rappresentato in 32 bit su x86.

Page 55: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 54

sono stati svolti su una macchina con le seguenti caratteristiche salienti:Processore: Intel Pentium 4 a 3GHz (2.998 GHz stimati)Memoria RAM: DDR a 400 MHz, 2048 MBPartizione di Swap: 1024 MB

Nel caso dell’esperimento con il tool KProbes/SystemTAP e stato adoperato un kernelcustom della distribuzione Linux Fedora Core 4, in particolare la versione 2.6.15-1.1830 FC4che rappresenta un kernel stabile. Le caratteristiche specifiche di tale kernel consistono nelfatto che e stato compilato con ottimizzazioni per il processore Intel Pentium 4 e che hauno schema di prelazione Preemptive (ossia low latency desktop). Per l’esperimento in cui estato impiegato il tool DSKI e stato impiegata la versione del kernel 2.6.12-RT-LIBERTOSconfigurata con le stesse opzioni appena descritte.

3.4 Preparazione esperimenti con KProbes/SystemTAP

In questa sezione ci proponiamo di descrivere gli esperimenti eseguiti attraverso il tool KPro-bes/SystemTAP. L’attenzione si concentrera dapprima sulla procedura di strumentazione perpoi spostarsi sui risultati ottenuti. La descrizione dei dettagli implementativi per realizzare ilprocedimento di probing (in particolare il file di script utilizzato) esula dagli scopi di questotesto e si rimanda alla [TESI PAOLO]. I tre esperimenti di cui si mostrano i risultati sonostati eseguiti per una durata di 6 ore ciascuno.

Avendo analizzato il sottosistema di gestione delle System Call in Linux e dal momentoche il tool di probing KProbes/SystemTAP puo inserire punti di strumentazione dinamica-mente si e deciso di inserire un punto in ingresso e uno in uscita dall’handler delle systemcall; per ottenere gli indirizzi fisici di questi due punti si puo utilizzare la mappa di sistemafornita in uscita dal processo di compilazione del kernel. Nel nostro caso siamo interessatiall’attraversamento delle locazioni di memoria che nel file entry.S, mostrato in precedenza,sono etichettate con le label system call e syscall exit.

Inseriti i due punti di strumentazione in ingresso e in uscita, attraverso una piccola rou-tine che legge il contenuto del registro EAX, e stato realizzato uno script, nel linguaggio diSystemTAP, che ricavi l’ID della system call invocata e il suo valore di ritorno. In tal modoe stato possibile monitorare tutte le possibili chiamate a system call dal lato utente.

Onde valutare i risultati sperimentali sono stati realizzati, per ogni esperimento, una seriedi grafici. In particolare si traccia una distribuzione di probabilita del numero di chiamatea system call in un secondo. Questo grafico risulta essere indicativo delle caratteristiche delworkload: quanto piu il sistema viene stressato tanto piu il numero di system call per secondoaumenta e quindi la pdf avra il suo massimo sempre piu spostato verso destra. Un secondografico (o una tabella) e indicativo delle frequenze di chiamata delle system call e questo dainformazione sulla particolare system call (ad esempio ci si aspetta che per un workload I/Obound la read venga chiamata con una frequenza maggiore rispetto alle altre). Infine unatabela riporta le percentuali di codici di uscita delle system call.

3.5 Preparazione esperimenti con DSKI

Una volta eseguiti gli esperimenti appena descritti, ci siamo proposti di impiegare per lo stessoscopo l’interfaccia DSKI. Purtroppo pero l’handler delle system call, che costituisce un puntodi incontro di tutte le chiamate a sistema, si trova in un file sorgente in linguaggio assembly

Armando Migliaccio
Note
ci sono alcuni riferimenti da correggere
Page 56: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 55

System call Sorgente C in cui e implementataread fs/read write.cwrite fs/read write.cllseek fs/read write.copen fs/open.cclose fs/open.cioctl fs/ioctl.cselect fs/select.crt sigaction kernel/signal.cmmap2 arch/i386/kernel/sys i386.cbrk mm/mmap.c

Tabella 3.1: Lista delle system call strumentate e relativa locazione.

(entry.S) e non C. Cio impedisce di poter sfruttare questo punto di convergenza e ci costringead inserire dei punti di strumentazione in ogni system call! Possiamo pero sfruttare i risultatidegli esperimenti eseguiti con l’altro tool e mostrati nel capitolo successivo nella sezione 4.1.Tali risultati mettono in evidenza che, stressando il sistema con i workload descritti nellasezione 3.2, non tutte le system call hanno una elevata probabilita di essere invocate anzialcune non vengono affatto chiamate mentre molte intervengono solo sporadicamente. Allaluce di questi fattori si e deciso di non monitorare con DSKI tutte le circa 300 system callma di limitarsi ad un sottoinsieme di 10 system call scelte proprio sulla base dei risultatisperimentali ottenuti con gli altri tool. La tabella 3.1 mostra l’elenco delle 10 system callscelte con il relativo file C in cui esse vengono implementate e qui di seguito ne forniamo unabreve descrizione:

• read usata per leggere da un file descriptor;

• write usata per scrivere in un file descriptor;

• llseek usata per muovere un puntatore all’interno di un file in scrittura o lettura;

• open usata per aprire un file o un dispositivo;

• close usata per chiudere un file descriptor;

• ioctl usata per controllare un device;

• select usata per la sincronizzazione in operazioni di I/O;

• rt sigaction usata per gestire i segnali;

• mmap2 usata per mappare pagine di memoria;

• brk usata per cambiare la lunghezza di un segmento dati allocato ad un processo.

Gli esperimenti si limiteranno a queste 10 system call e avranno, in tal caso, una duratadi 1 ora. Il motivo per cui si e preferito ridurre ad un sesto la durata del monitoraggio stanel fatto che gia con un esperimento della durata di 1 ora il file binario di uscita assumedimensioni di svariati MB! Se si applica ad un file binario di 14 MB il semplicissimo filtro

Page 57: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 56

di narrazione viene resituito un file xml di 180 MB! Quindi si e preferito ridurre la duratadell’esperimento anche perche i workload impiegati durano meno di un’ora dopodiche vengonorimessi in esecuzione quindi teoricamente non ci dovrebbero essere differenze tra i risultati sequesti vengono normalizzati. Nelle prossime sezioni descriveremo in dettaglio la procedura distrumentazione (a differenza del caso KProbes/SystemTAP) mentre nel capitolo successivodaremo uno sguardo ai risultati sperimentali ottenuti.

Prima di poter inserire qualunque punto di strumentazione e stato necessario definire ilseguente namespace file chiamato syscall.ns e che deve essere posizionato in<RootKernelLibeRTOS>/scripts/dski:

#!lib.parsers.ns_parser_v1namespace {

desc = ""family SYS_IO_FAM 21 {

desc = "Questa famiglia contiene le entita definite perstrumentare le system call di IO."

shortdesc = "System call di I/O"event SYS_READ 0 {

desc = ""kernelf = ""printf = "print_int"shortdesc = "Invocata la read."

}event SYS_WRITE 1 {

desc = ""kernelf = ""printf = "print_int"shortdesc = "Invocata la write."

}event SYS_OPEN 2 {

desc = ""kernelf = ""printf = "print_int"shortdesc = "Invocata la open."

}event SYS_CLOSE 3 {

desc = ""kernelf = ""printf = "print_int"shortdesc = "Invocata la close."

}event SYS_IOCTL 4 {

desc = ""kernelf = ""printf = "print_int"shortdesc = "Invocata la ioctl."

}

Page 58: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 57

event SYS_SELECT 5 {desc = ""kernelf = ""printf = "print_int"shortdesc = "Invocata la select."

}event SYS_LLSEEK 6 {

desc = ""kernelf = ""printf = "print_int"shortdesc = "Invocata la llseek."

}}family SYS_OTHER_FAM 22 {

desc = ""shortdesc = "System call generiche"event SYS_MMAP2 0 {

desc = ""kernelf = ""printf = "print_int"shortdesc = "Invocata la mmap2."

}event SYS_BRK 1 {

desc = ""kernelf = ""printf = "print_int"shortdesc = "Invocata la brk."

}event SYS_RT_SIGACTION 2 {

desc = ""kernelf = ""printf = "print_int"shortdesc = "Invocata la rt_sigaction."

}}

}

Come si puo vedere sono state utilizzate esclusivamente entita di tipo Evento ed esse sonoraggruppate in due famiglie:

1. SYS IO FAM che comprende gli eventi da associare alle system call che eseguono opera-zioni di IO;

2. SYS OTHER FAM che comprende gli eventi associati alle system call che operano sullamemoria e a quelle maggiormente invocate quando il sistema e stressato con un workloaddi tipo CPU bound.

Da notare che tutti gli eventi loggano un extra dato che viene fornito in uscita secondo ilformato intero grazie alla scelta della funzione print int.

Page 59: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 58

A questo punto e stato necessario aggiungere tale file all’elenco dei file da “parsare”, elencoche si trova nel Makefile del kernel alla label dskifamilies. Quindi si e eseguito il comandomake dskifamilies che rigenera i file di sistema che definiscono le macro di strumentazione(datastream families.h...). Eseguito il parsing e stato necessario inserire a mano i punti distrumentazione nelle varie system call locate come da tabella 3.1. A titolo di esempio vediamocome e stato modificato il codice della system call close:

asmlinkage long sys_close(unsigned int fd){

struct file * filp;struct files_struct *files = current->files;

spin_lock(&files->file_lock);if (fd >= files->max_fds)

goto out_unlock;filp = files->fd[fd];if (!filp)

goto out_unlock;files->fd[fd] = NULL;FD_CLR(fd, files->close_on_exec);__put_unused_fd(files, fd);spin_unlock(&files->file_lock);

long ret;ret = filp_close(filp, files);

if (ret >= 0) {DSTRM_EVENT(SYS_IO_FAM, SYS_CLOSE, 0,

sizeof(long), (void*)&ret);} else {

DSTRM_EVENT(SYS_IO_FAM, SYS_CLOSE, 1,sizeof(long), (void*)&ret);

}

return ret;

out_unlock:spin_unlock(&files->file_lock);

long errcode;errcode = -EBADF;

DSTRM_EVENT(SYS_IO_FAM, SYS_CLOSE, 1,sizeof(long), (void*)&errcode);

return -EBADF;}

Page 60: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 59

Per capire quello che e stato fatto ricordiamo che noi siamo interessati a sapere nonsolo quante volte una system call viene invocata ma anche quale eventuale codice d’errorerestituisce. Tutte le system call ritornano valori positivi nel caso in cui le operazioni vadanoa buon fine mentre il valore e compreso tra circa -150 e -1 nel caso in cui ci siano stati deiproblemi. Il codice di uscita indica, in base al suo significato, il problema accorso. Per talmotivo non basta inserire un punto di strumentazione in ogni punto di uscita dalla systemcall ma dobbiamo discriminare i due casi a meno che non sia evidente che il valore di ritornodebba per forza essere positivo o negativo. Questo spiega perche nella close sono stati inseriti3 punti di strumentazione. Inoltre e stata adottata una evidente convenzione che ci permettedi risalire al codice di uscita o anche semplicemente all’esito della chiamata. Il campo TAGdegli eventi, campo che corrisponde al terzo parametro della macro, viene impostato a 0 se ilvalore di ritorno e non negativo, a 1 altrimenti. Questo serve per discriminare tra il caso incui tutto sia andato bene e il caso opposto. L’extra dato invece viene sempre uguagliato alvalore di ritorno, positivo o negativo che sia.

A questo punto e stato necessario ricompilare il kernel dopo aver abilitato, dal menu diconfigurazione, la nostre due nuove famiglie SYS IO FAM e SYS OTHER FAM.

Rimane da creare un file di configurazione in cui vengono abilitati tutti gli eventi associatialle system call e vengono settati i file di output nonche la frequenza e la durata dell’espe-rimento. In effetti basterebbe un solo file di configurazione ma il file binario di output devenecessariamente essere distinto nei tre casi quindi sono stati creati tre file separati. Per quantorigurarda la frequenza, questa viene impostata a 100 volte al secondo mentre la durata dell’e-sperimento viene settata a 3600 secondi per i motivi discussi in precedenza. Quello che seguee il file di configurazione nel caso CPU bound ma niente cambia per gli altri 2 esperimenti(IO e MEMORY bound) a parte il nome del file di uscita.

#!lib.parsers.expt_parser_v1

EXPERIMENT_DURATION 3600

SNAPSHOT_FREQUENCY 100

BINARY_TARGET "cpubound.bin"

NAMESPACE_FILE "/usr/src/linux-2.6.12-LIBERTOS/scripts/dski/syscall.ns"

DSTRM_EVENT SYS_IO_FAM 21 SYS_OPEN 2DSTRM_EVENT SYS_IO_FAM 21 SYS_CLOSE 3DSTRM_EVENT SYS_IO_FAM 21 SYS_SELECT 5DSTRM_EVENT SYS_IO_FAM 21 SYS_WRITE 1DSTRM_EVENT SYS_IO_FAM 21 SYS_READ 0DSTRM_EVENT SYS_IO_FAM 21 SYS_IOCTL 4DSTRM_EVENT SYS_IO_FAM 21 SYS_LLSEEK 6DSTRM_EVENT SYS_OTHER_FAM 22 SYS_MMAP2 0DSTRM_EVENT SYS_OTHER_FAM 22 SYS_BRK 1DSTRM_EVENT SYS_OTHER_FAM 22 SYS_RT_SIGACTION 2

Page 61: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 60

A questo punto gli esperimenti possono essere messi in esecuzione attraverso il solitocomando dski demon -e file.dski e quindi verrano avviati i relativi benchmark attraversodei semplici file di script onde rimetterli in esecuzione (dato che durano meno di un’ora). Allafine si otterranno i tre file binari cpubound.bin, iobound.bin e membound.bin.

Anche in questo caso siamo interessati ad ottenere le stesse statistiche nonche gli stessitipi di grafici ottenuti per il caso di SystemTAP. Per ottenere i grafici (e le tabelle) chepresenteremo nella sezione 4.1 e stato necessario un lungo e tedioso procedimento manualeche e consistito nell’eseguire una lunga serie di passi che non e stato possibile automatizzaree proprio per questo motivo tutte le operazioni sono state ripetute per ben tre volte, una perogni tipo di workload! Da questo punto di vista DSKI si mostra assai piu agevole perche offrela possibilita di scrivere dei filtri ad hoc che possiamo riutilizzare ogni volta che vogliamo eche automatizzano tutto il lavoro. Per l’occasione sono stati realizzati tre filtri onde ottenererispettivamente la pdf del numero di chiamate al secondo, la percentuale di chiamata dellesingole system call e la tabella finale con i codici di uscita delle system call invocate. Ilcodice e la descrizione di tali filtri sono riportati nella sezione C. Nelle prossime sezioni cioccuperemo di capire che cosa fanno questi filtri e non come.

3.5.1 Filtro event pdf

Il filtro event pdf viene impiegato per generare la pdf delle chiamate alle system call ognisecondo. Il filtro e capace di generare due file in uscita da cui ottenere la pdf:

1. *.dat e il file che contiene i valori su cui eseguire un plotting onde ottenere il grafico;

2. Commands.m e il file che contiene tutti i comandi necessari all’applicazione octave pertracciare il grafico.

Una volta selezionato dall’elenco esso propone di inserire una serie di parametri di cuimolti di default. La figura 3.1 mostra la finestra che appare all’utente nel momento in cui ilfiltro viene aggiunto alla pipeline.

Figura 3.1: Finestra di dialogo per il filtro event pdf.

Armando Migliaccio
Note
eviterei di usare la parola tedioso
Page 62: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 61

I vari campi della form sono abbastanza autoesplicativi grazie alle etichette e si rimandaalla sezione C.1 per maggiori informazioni. Quello che interessa in questa sezione e che unavolta applicato il filtro ed eseguito il comando octave Commands.m esso genera un’immagine.jpg o .png che mostra la pdf desiderata con relativa media e deviazione standard nonche ilmassimo numero di chiamate fatte in un secondo. Si faccia attenzione al fatto che in realtaquesto particolare filtro non necessariamente deve essere usato per le system call ne siamovincolati ad ottenere la pdf delle chiamate su un secondo. Il filtro ha valore generale, puoessere usato per tutti gli eventi ed e possibile precisare una durata dell’intervallo maggiore ominore (frazione) di un secondo da cui il motivo per cui si e deciso di denominarlo event pdfe non syscall pdf.

3.5.2 Filtro event percent

Il filtro event percent e stato costruito per generare il grafico che mostra le percentuali dichiamata delle dieci system call monitorare. Il filtro opera come quello descritto in precedenzae in particolare genera un file in cui sono contenuti i comandi di plottaggio e un file per ognisystem call che contiene i valori da tracciare. Il motivo per cui i dati vengono suddivisi inpiu file e legato essenzialmente al fatto che in tale circostanza viene impiegata l’applicazionegnuplot e non octave e siamo interessati ad ottenere un grafico a barre in cui ogni barra siaassociata ad una system call specifica. L’unico modo in gnuplot per distinguere con coloridiversi piu grafici e suddividere in piu file i valori da tracciare da cui la necessita di un fileper ogni system call. La figura 3.2 mostra quali parametri l’utente puo immettere in ingressoal filtro.

Figura 3.2: Finestra di dialogo per il filtro event percent.

Page 63: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 3. CASO DI STUDIO 62

Anche in questo caso ogni commento e superfluo dato che molte opzioni servono a settareil path o la grafica dell’immagine. Una volta applicato il filtro sara necessario eseguire ilcomando gnuplot Commands.gnuplot e si otterra un’immagine .jpg o .png con il graficoa barre desiderato. A differenza che nel caso precedente questo filtro non ha un utilita“universale” nel senso che, come si evince dal suo codice mostrato in sezione C.2, esso e statoappositamente costruito per le system call monitorare. Infatti supporta di default l’elencodelle system call di cui tracciare il grafico e anche i file dati di uscita hanno una nomenclaturache dipende da questo elenco per cui e necessario apportargli delle modifiche se si vuole“riciclarlo” in altri contesti.

3.5.3 Filtro event tomysql

L’ultimo filtro realizzato ad hoc e chiamato event tomysql. Esso offre la possibilita di ot-tenere una tabella in cui vengono mostrati i codici d’uscita delle system call. Precisamentesiamo interessati ad una tabella in cui per ogni coppia (syscall, outcode) viene fornita larelativa percentuale di occorrenza. Avendo necessita di una tabella la cosa piu ovvia che civiene in mente e di portare in un database tutti gli eventi con le relative informazioni e quindiottenere la tabella attraverso una query. Il filtro in questione esegue per l’appunto questaoperazione come viene mostrato nella sezione C.3. La figura 3.3 mostra la finestra di dialogodi cui l’utente deve riempire i campi per consentire questa operazione.

Figura 3.3: Finestra di dialogo per il filtro event tomysql.

Tutte le informazioni immesse servono soltanto a stabilire la connessione col databasee a selezionarlo. Questo suggerisce che anche questo filtro, come quello event pdf ha unvalore aggiunto e cioe puo essere utilizzato per memorizzare eventi di qualsiasi genere inqualunque database dato che non vi e in alcun modo una dipendenza con il nostro esperimento.Naturalmente e comunque necessario costruire a priori il database e poi eseguire a mano lequery che possono interessarci. Il codice SQL relativo alla creazione del database e alle queryper ottenere la tabella desiderata sono mostrati nella sezione D.

Una volta costruiti i filtri e applicati ai tre file binari cpubound.bin, iobound.bin emembound.bin attraverso il solito comando dstream filter.py -c *.filter si ottengono irisultati che mostriamo nel capitolo successivo.

Page 64: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Capitolo 4

Risultati sperimentali

In questo ultimo capitolo ci preoccuperemo di mostrare i risultati ottenuti dall’esecuzionedegli esperimenti descritti nel capitolo precedente. Cominceremo con i risultati ottenuti mo-nitorando le system call con il tool KProbes/SystemTAP dato che questi risultati sono statiesaminati per prendere la decisione sulle system call da monitorare con DSKI. Proseguiremoquindi con i risultati relativi agli esperimenti monitorati con DSKI e infine deriveremo lerelative conclusioni.

4.1 Risultati KProbes/SystemTAP

In tale sezione vengono mostrati i risultati del monitoraggio di tutte le circa 300 system call at-traverso il tool KProbes/SystemTAP. Le tre sezioni seguenti mostrano gli effetti relativamenteal carico impiegato.

4.1.1 Caso CPU bound

Il primo esperimento consiste nell’esecuzione del workload CPU bound descritto nella sezione3.2.1 e parallelamente nell’utilizzo del tool per catturare le informazioni desiderate. Dall’espe-rimento ci si aspetta che le frequenze di chiamata per secondo a system call si distribuiscanocon una distribuzione di tipo esponenziale decrescente; infatti dal momento che la CPU eper la maggior parte del tempo impegnata ad effettuare calcoli numerici ci si aspetta che laprobabilita di avere n chiamate in un secondo diminuisca esponenzialmente con l’amunetaredi n. I risultati ottenuti approssimativamente concordano con le predizioni tenendo contocomunque che vi sono dei picchi spuri dovuti principalmente alle attivita secondarie di IOsvolte dal benchmarck (stampa a video di alcune informazioni etc.) e che generano questiimpulsi nel grafico (figura 4.1); a tale motivazione sono imputabili anche le componenti intor-no a 140 e 220, che in ogni caso corrispondono complessivamente ad una probabilita moltobassa. Calcolando la media della PDF ottenuta si ricava µ = 111.86 mentre la deviazionestandard e σ = 360.41 il che risulta essere in sintonia con il fatto che il workload e di tipoCPU bound, infatti una media di circa 111 chiamate a system call al secondo e davvero moltobassa, considerando che per un calcolatore un intervallo di 1 secondo e un’enormita.

La PDF del numero di chiamate al secondo da un’informazione generale sulle caratteri-stiche del workload. Quello che e interessante analizzare, a questo punto, sono le frequenzerelative delle singole system call invocate dal workload. Tali informazioni sono riportate nelle

63

Armando Migliaccio
Note
nn sono d'accordo con questa affermazione, eliminatela
Armando Migliaccio
Note
illustrate prima cosa misurate e cosa illustrate
Armando Migliaccio
Note
cosa? 140 patane? cipolle? :-)
Page 65: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 64

Figura 4.1: PDF numero chiamate system call al secondo, caso CPU

tabelle 4.1 e 4.2 e nel grafico a barre di figura 4.2 sono riportate le percentuali di chiamatadelle system call piu invocate.

Come e possibile evincere dalle tabelle riportate, in cui sono evidenziate in grassettole system call con una percentuale di chiamata maggiore del 5%, le syscall maggiormenteinvocate sono la rt sigprocmask e la rt sigaction; esse vengono impiegate per gestire l’inviodi segnali tra processi concorrenti, quindi e ragionevole supporre tale risultato in sintonia conle previsioni riguardanti un carico di tipo CPU bound. In effetti nelle applicazioni di tipoCPU bound vengono spesso utilizzate tecniche di programmazione concorrente per ottimizzarel’utilizzo del processore.

In ultima analisi, osserviamo adesso i codici di ritorno restituiti dalle system call invocateriportati nelle tabelle 4.3 e 4.4. Ovviamente non sempre i codici di ritorno negativi rappre-sentano una situazione di errore, ma il tutto dipende dalla semantica della particolare systemcall. In ogni caso per conoscere il significato di ogni codice fare riferimento all’appendice E.Nell’analisi di tali tabelle bisogna pero tenere presente che si e eseguito l’esperimento utiliz-zando un kernel stabile e che pertanto la maggior parte delle system call non restituisconocodici particolari.

4.1.2 Caso IO bound

In questo secondo esperimento e stato applicato il workload I/O bound. I risultati che cisi aspetta di trovare ovviamente sono diversi rispetto al caso precedente; in tal caso infatti,poiche il workload in questione si suppone debba effettuare molte operazioni di I/O, ci siaspetta che la distribuzione sia sempre esponenziale, ma con un fattore di scala maggiore, datoche sicuramente il numero complessivo di chiamate al secondo sara superiore. I risultati sonomostrati in figura 4.3; come e possibile notare, e chiaramente visibile l’andamento esponenziale

Armando Migliaccio
Note
codici d'errore
Armando Migliaccio
Note
come sopra
Page 66: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 65

KProbes/SystemTAP – CPU BOUND – Frequenze invocazioni – Parte 1ID Nome Numero Chiamate %

0 restart syscall 20123 00.833 read 105159 04.354 write 130923 05.425 open 112139 04.646 close 283215 11.727 waitpid 35444 01.47

10 unlink 1089 00.0511 execve 15166 00.6312 chdir 3904 00.1613 time 16346 00.6815 chmod 55 00.0019 lseek 110 00.0020 getpid 789 00.0327 alarm 10816 00.4529 pause 5 00.0033 access 28846 01.1936 sync 3126 00.1337 kill 2379 00.1042 pipe 4422 00.1845 brk 36936 01.5354 ioctl 188003 07.7860 umask 167 00.0163 dup2 14262 00.5964 getppid 899 00.0465 getpgrp 899 00.0466 setsid 6 00.0075 setrlimit 90 00.0077 getrusage 44717 01.8578 gettimeofday 35186 01.4685 readlink 140 00.0191 munmap 40985 01.7094 fchmod 72 00.0096 getpriority 2880 00.1297 setpriority 1446 00.0699 statfs 72 00.00

100 fstatfs 36 00.00

Tabella 4.1: System Call invocate nell’esperimento CPU bound con SystemTAP/KProbes conID da 0 a 100. In grassetto sono evidenziate le system call con una percentuale di chiamatemaggiore del 5%.

Page 67: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 66

KProbes/SystemTAP – CPU BOUND – Frequenze invocazioni – Parte 2ID Nome Numero Chiamate %

102 socketcall 130284 05.39114 wait4 2016 00.08118 fsync 13 00.00119 sigreturn 22071 00.91120 clone 19717 00.82122 newuname 1011 00.04125 mprotect 41310 01.71133 fchdir 110 00.00140 llseek 4081 00.17141 getdents 5928 00.25142 select 31844 01.32146 writev 12 00.00149 sysctl 3456 00.14162 nanosleep 14230 00.59168 poll 5068 00.21174 rt sigaction 346470 14.34175 rt sigprocmask 252364 10.44183 getcwd 173 00.01190 vfork 385 00.02191 getrlimit 4274 00.18192 mmap2 163763 06.78195 stat64 70259 02.91196 lstat64 3045 00.13197 fstat64 103357 04.28199 getuid 795 00.03200 getgid 789 00.03201 geteuid 801 00.03202 getegid 795 00.03205 getgroups 1004 00.04206 setgroups 12 00.00207 fchown 72 00.00213 setuid 18 00.00214 setgid 6 00.00220 getdents64 696 00.03221 fcntl64 19236 00.80240 futex 376 00.02243 set thread area 14396 00.60256 epoll wait 4319 00.18258 set tid address 3456 00.14265 clock gettime 3401 00.14268 statfs64 55 00.00

Tabella 4.2: System Call invocate nell’esperimento CPU bound con SystemTAP/KProbescon ID da 101 a 300. In grassetto sono evidenziate le system call con una percentuale dichiamate maggiore del 5%.

Page 68: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 67

KProbes/SystemTAP – CPU BOUND – Codici di Ritorno – Parte 1Nome OK % Altri Codici

restart syscall 100.00 Nessunoread 100.00 Nessuno

write 100.00 Nessunoopen 097.42 ENOENT = 2.57, ENXIO = 0.01close 099.48 EBADF = 0.52

waitpid 051.04 ECHILD = 48.96unlink 057.58 ENOENT = 42.42execve 094.92 ENOENT = 4.35, ENOEXEC = 0.73chdir 100.00 Nessunotime 100.00 Nessuno

chmod 100.00 Nessunolseek 100.00 Nessuno

getpid 100.00 Nessunoalarm 100.00 Nessunopause 100.00 Nessunoaccess 049.46 ENOENT = 50.51, EACCESS = 0.03

sync 100.00 Nessunokill 100.00 Nessuno

pipe 100.00 Nessunobrk 100.00 Nessuno

ioctl 075.35 EAGAIN = 0.77, EINVAL = 11.59, ENOTTY= 0.8, EADDRNOTAVAIL = 11.49

umask 100.00 Nessunodup2 100.00 Nessuno

getppid 100.00 Nessunogetpgrp 100.00 Nessuno

setsid 100.00 Nessunosetrlimit 100.00 Nessuno

getrusage 100.00 Nessunogettimeofday 100.00 Nessuno

readlink 100.00 Nessunomunmap 100.00 Nessunofchmod 100.00 Nessuno

getpriority 100.00 Nessunosetpriority 100.00 Nessuno

statfs 100.00 Nessunofstatfs 100.00 Nessuno

Tabella 4.3: Codici di ritorno delle system call invocate nell’esperimento CPU bound conSystemTAP/KProbes, primo gruppo.

Page 69: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 68

KProbes/SystemTAP – CPU BOUND – Codici di Ritorno – Parte 2Nome OK % Altri Codici

socketcall 099.81 ENOENT = 0.14wait4 099.70 ECHILD = 0.03fsync 100.00 Nessuno

sigreturn 090.15 EINTR = 9.85clone 100.00 Nessuno

newuname 100.00 Nessunomprotect 100.00 Nessuno

fchdir 100.00 Nessunollseek 099.85 ESPIPE = 0.15

getdents 100.00 Nessunoselect 100.00 Nessuno

writev 100.00 Nessunosysctl 100.00 Nessuno

nanosleep 100.00 Nessunopoll 071.61 EINTR = 28.39

rt sigaction 099.17 EINVAL = 0.83rt sigprocmask 100.00 Nessuno

getcwd 100.00 Nessunovfork 100.00 Nessuno

getrlimit 100.00 Nessunommap2 100.00 Nessunostat64 069.75 ENOENT = 30.25lstat64 100.00 Nessunofstat64 100.00 Nessunogetuid 100.00 Nessunogetgid 100.00 Nessuno

geteuid 100.00 Nessunogetegid 100.00 Nessuno

getgroups 100.00 Nessunosetgroups 100.00 Nessuno

fchown 100.00 Nessunosetuid 066.67 EPERM = 33.33setgid 100.00 Nessuno

getdents64 100.00 Nessunofcntl64 100.00 Nessuno

futex 100.00 Nessunoset thread area 100.00 Nessuno

epoll wait 100.00 Nessunoset tid address 100.00 Nessunoclock gettime 100.00 Nessuno

statfs64 100.00 Nessuno

Tabella 4.4: Codici di ritorno delle system call invocate nell’esperimento CPU bound conSystemTAP/KProbes, secondo gruppo.

Page 70: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 69

Figura 4.2: KProbes/SystemTAP, caso CPU bound. Percentuali del numero di invocazionidelle system call maggiormente invocate.

decrescente della PDF, anche se sono presenti componenti spurie come nel caso precedente. Intal caso la media risulta µ = 822.29 cioe circa otto volte maggiore rispetto a prima, mentre ladeviazione standard e σ = 3446.5; una σ cosı elevata, oltre ad avere un riscontro grafico, dalmomento che la PDF I/O bound e maggiormente distribuita sull’asse delle ascisse, possiedeanche una motivazione tecnica, poiche in alcuni intervalli il workload era bloccato in attesadel completamento delle operazioni di I/O, cosicche il numero di chiamate a system call alsecondo era basso, in altri invece era in piena attivita.

Anche in questo caso riportiamo le tabelle con le frequenze relative di invocazioni systemcall al secondo (tabelle 4.5 e 4.6).

Nel caso I/O bound e possibile osservare che le system call che vengono invocate con unafrequenza maggiore del 5% sono solo tre ed in particolare la read, la write e la llseek; si notila predominanza di tali system call rispetto alle altre, tanto e vero che circa il 93% delle voltee stata invocata una di esse. Questo fatto del resto e in pieno accordo con le previsioni, dalmomento che un carico di tipo I/O bound effettuera molte operazioni di scrittura e lettura, ilche spiega la loro predominanza (si ricordi che la llseek serve per spostare l’offset all’internodi un file aperto in lettura/scrittura).

Adesso esaminiamo i codici di ritorno riportati nelle tabelle 4.7 e 4.8.Bisogna tuttavia notare che, dal momento che le system call maggiormente invocate sono

la read, la write e la llseek mentre il resto ha una frequenza di invocazione al di sottodell’1%, tali risultati sono significativi esclusivamente per le tre suddette system call. Si vedeinfatti che la read e la write praticamente non falliscono mai, mentre la llseek ha anch’essaun tasso di successo prossimo al 100%.

4.1.3 Caso MEMORY bound

Nel terzo esperimento e stato applicato il workload appositamente realizzato per sforzare lamemoria del sistema descritto in precedenza. Nel caso MEMORY bound, tuttavia, data lanatura lineare e semplice del workload adoperato, ci si aspettava una PDF completamente

Page 71: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 70

KProbes/SystemTAP – I/O BOUND – Frequenze invocazioni – Parte 1ID Nome Numero Chiamate %

0 restart syscall 3021 00.023 read 6636768 37.364 write 5015786 28.245 open 83926 00.476 close 220403 01.247 waitpid 3075 00.02

10 unlink 6640 00.0411 execve 68 00.0012 chdir 9 00.0013 time 15332 00.0920 getpid 15 00.0027 alarm 4367 00.0229 pause 5 00.0033 access 161 00.0036 sync 4320 00.0237 kill 2159 00.0142 pipe 60 00.0045 brk 204 00.0054 ioctl 185280 01.0460 umask 3 00.0063 dup2 140 00.0064 getppid 15 00.0065 getpgrp 15 00.0066 setsid 6 00.0075 setrlimit 90 00.0078 gettimeofday 93104 00.5285 readlink 30 00.0091 munmap 24176 00.1493 ftruncate 2160 00.0194 fchmod 71 00.0096 getpriority 2880 00.0297 setpriority 1446 00.0199 statfs 72 00.00

100 fstatfs 36 00.00

Tabella 4.5: System Call invocate nell’esperimento I/O bound con SystemTAP/KProbes conID da 0 a 100. In grassetto sono evidenziate le system call con una percentuale di chiamatemaggiore del 5%.

Page 72: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 71

KProbes/SystemTAP – I/O BOUND – Frequenze invocazioni – Parte 2ID Nome Numero Chiamate %102 socketcall 129859 00.73114 wait4 15 00.00118 fsync 51876 00.29119 sigreturn 5857 00.03120 clone 1559 00.01122 newuname 35 00.00125 mprotect 212 00.00140 llseek 4943308 27.83141 getdents 5928 00.03142 select 31980 00.18146 writev 15 00.00149 sysctl 17 00.00162 nanosleep 11102 00.06168 poll 5086 00.03174 rt sigaction 133219 00.75175 rt sigprocmask 56288 00.32183 getcwd 9 00.00191 getrlimit 116 00.00192 mmap2 24949 00.14195 stat64 10128 00.06196 lstat64 2880 00.02197 fstat64 34043 00.19199 getuid 21 00.00200 getgid 15 00.00201 geteuid 27 00.00202 getegid 21 00.00205 getgroups 6 00.00206 setgroups 12 00.00207 fchown 71 00.00213 setuid 18 00.00214 setgid 6 00.00220 getdents64 36 00.00221 fcntl64 3312 00.02240 futex 94 00.00243 set thread area 68 00.00256 epoll wait 4320 00.02258 set tid address 17 00.00

Tabella 4.6: System Call invocate nell’esperimento I/O bound con SystemTAP/KProbes conID da 101 a 300. In grassetto sono evidenziate le system call con una percentuale di chiamatemaggiore del 5%.

Page 73: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 72

KProbes/SystemTAP – I/O BOUND – Codici di Ritorno – Parte 1Nome OK % Altri Codici

restart syscall 099.97 EINTR = 0.03read 100.00 Nessuno

write 100.00 Nessunoopen 099.88 ENOENT = 0.1, ENXIO = 0.02close 099.00 EBADF = 1

waitpid 050.37 ECHILD = 49.63unlink 098.67 ENOENT = 1.33execve 100.00 Nessunochdir 100.00 Nessunotime 100.00 Nessuno

getpid 100.00 Nessunoalarm 100.00 Nessunopause 100.00 Nessunoaccess 042.86 ENOENT = 49.69, EACCESS = 7.45

sync 100.00 Nessunokill 100.00 Nessuno

pipe 100.00 Nessunobrk 100.00 Nessuno

ioctl 75.88 EAGAIN = 0.78, EINVAL = 11.67, ENOTTY= 0.01, EADDRNOTAVAIL = 11.66

umask 100.00 Nessunodup2 100.00 Nessuno

getppid 100.00 Nessunogetpgrp 100.00 Nessuno

setsid 100.00 Nessunosetrlimit 100.00 Nessuno

gettimeofday 100.00 Nessunoreadlink 100.00 Nessunomunmap 100.00 Nessunoftruncate 100.00 Nessuno

fchmod 100.00 Nessunogetpriority 100.00 Nessunosetpriority 100.00 Nessuno

statfs 100.00 Nessunofstatfs 100.00 Nessuno

Tabella 4.7: Codici di ritorno delle system call invocate nell’esperimento I/O bound conSystemTAP/KProbes, primo gruppo.

Page 74: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 73

KProbes/SystemTAP – I/O BOUND – Codici di Ritorno – Parte 2Nome OK % Altri Codici

socketcall 099.98 ENOENT = 0.01wait4 060.00 ECHILD = 40fsync 100.00 Nessuno

sigreturn 062.57 EINTR = 37.43clone 100.00 Nessuno

newuname 100.00 Nessunomprotect 100.00 Nessuno

llseek 099.91 EINVAL = 0.09getdents 100.00 Nessuno

select 100.00 Nessunowritev 100.00 Nessunosysctl 100.00 Nessuno

nanosleep 100.00 Nessunopoll 071.35 EINTR = 28.65

rt sigaction 097.84 EACCESS = 2.16rt sigprocmask 100.00 Nessuno

getcwd 100.00 Nessunogetrlimit 100.00 Nessunommap2 100.00 Nessunostat64 098.84 ENOENT = 1.16lstat64 100.00 Nessunofstat64 100.00 Nessunogetuid 100.00 Nessunogetgid 100.00 Nessuno

geteuid 100.00 Nessunogetegid 100.00 Nessuno

getgroups 100.00 Nessunosetgroups 100.00 Nessuno

fchown 100.00 Nessunosetuid 066.67 EPERM = 33.33setgid 100.00 Nessuno

getdents64 100.00 Nessunofcntl64 100.00 Nessuno

futex 100.00 Nessunoset thread area 100.00 Nessuno

epoll wait 100.00 Nessunoset tid address 100.00 Nessuno

Tabella 4.8: Codici di ritorno delle system call invocate nell’esperimento I/O bound conSystemTAP/KProbes, secondo gruppo.

Page 75: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 74

Figura 4.3: PDF numero chiamate system call al secondo, caso I/O

diversa dalle precedenti, con caratteristiche abbastanza regolari. Il risultato, mostrato infigura 4.4, ci mostra una PDF chiaramente gaussiana; in parte cio e dovuto alla naturacostante del carico, che nella frazione di tempo considerato effettua quasi sempre lo stessonumero di chiamate al sistema. La media della PDF in questione risulta µ = 526.74 mentrela deviazione standard σ = 621.7.

Nelle tabelle 4.9 e 4.10 che riportano le frequenze di invocazioni a system call, si puo no-tare in questo caso una netta predominanza della brk con un frequenza del 93% circa. Questorisultato e in accordo con le previsioni, in quanto la brk ha lo scopo di modificare la dimen-sione in memoria assegnata al segmento dati di un processo da parte del sistema operativo.Dal momento che il workload impiegato nell’esperimento e stato studiato appositamente perstressare il sottosistema di gestione della memoria assegnata ai processi, tale risultato era ineffetti piu che prevedibile.

Per quanto riguarda i codici di ritorno, riportati nelle tabelle 4.11 e 4.12, dal momentoche tutte le system call vengono invocate con una frequenza al di sotto del 2% mentre labrk viene invocata quasi sempre, il risultato maggiormente significativo riguarda il tasso disuccesso di quest’ultima. Si vede infatti che essa praticamente non fallisce mai, avendo untasso di successo del 100%.

4.2 Risultati DSKI

Le successive tre sezioni mostrano i risultati dell’indagine sulle 10 system call monitorate conDSKI a seconda del carico impiegato.

Page 76: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 75

KProbes/SystemTAP – MEMORY BOUND – Frequenze invocazioni – Parte 1ID Nome Numero Chiamate %

0 restart syscall 2371 00.023 read 53057 00.344 write 69504 00.445 open 41213 00.266 close 174547 01.117 waitpid 4209 00.03

10 unlink 140 00.0011 execve 872 00.0112 chdir 6 00.0013 time 15105 00.1020 getpid 12 00.0027 alarm 4128 00.0329 pause 11 00.0033 access 890 00.0137 kill 2145 00.0142 pipe 12 00.0045 brk 14622839 93.1554 ioctl 184482 01.1863 dup2 48 00.0064 getppid 12 00.0065 getpgrp 12 00.0066 setsid 6 00.0075 setrlimit 90 00.0078 gettimeofday 31698 00.2085 readlink 30 00.0091 munmap 22593 00.1494 fchmod 70 00.0096 getpriority 2456 00.0297 setpriority 1234 00.0199 statfs 70 00.00

100 fstatfs 36 00.00

Tabella 4.9: System Call invocate nell’esperimento MEMORY bound con System-TAP/KProbes con ID da 0 a 100. In grassetto sono evidenziate le system call con unapercentuale di chiamate maggiore del 5%.

Page 77: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 76

KProbes/SystemTAP – MEMORY BOUND – Frequenze invocazioni – Parte 2ID Nome Numero Chiamate %102 socketcall 128928 00.82114 wait4 12 00.00118 fsync 8 00.00119 sigreturn 6198 00.04120 clone 2112 00.01122 newuname 12 00.00125 mprotect 1768 00.01140 llseek 30 00.00141 getdents 5078 00.03142 select 31598 00.20146 writev 6 00.00162 nanosleep 11103 00.07168 poll 5611 00.04174 rt sigaction 125725 00.80175 rt sigprocmask 62030 00.40183 getcwd 6 00.00191 getrlimit 96 00.00192 mmap2 27975 00.18195 stat64 9865 00.06196 lstat64 2456 00.02197 fstat64 35524 00.23199 getuid 18 00.00200 getgid 12 00.00201 geteuid 24 00.00202 getegid 18 00.00206 setgroups 12 00.00207 fchown 70 00.00213 setuid 18 00.00214 setgid 6 00.00220 getdents64 36 00.00221 fcntl64 2859 00.02240 futex 87 00.00243 set thread area 872 00.01256 epoll wait 4311 00.03

Tabella 4.10: System Call invocate nell’esperimento MEMORY bound con System-TAP/KProbes con ID da 101 a 300.

Page 78: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 77

KProbes/SystemTAP – MEMORY BOUND – Codici di Ritorno – Parte 1Nome OK % Altri Codici

restart syscall 099.96 EINTR = 0.04read 100.00 Nessuno

write 100.00 Nessunoopen 099.87 ENOENT = 0.1, ENXIO = 0.03close 100.00 Nessuno

waitpid 049.99 ECHILD = 50.01unlink 050.00 ENOENT = 50execve 100.00 Nessunochdir 100.00 Nessunotime 100.00 Nessuno

getpid 100.00 Nessunoalarm 100.00 Nessunopause 100.00 Nessunoaccess 001.35 ENOENT = 98.65

kill 100.00 Nessunopipe 100.00 Nessunobrk 100.00 Nessuno

ioctl 064.44 EAGAIN = 0.67, EINVAL = 11.64, EADDR-NOTAVAIL = 23.26

dup2 100.00 Nessunogetppid 100.00 Nessunogetpgrp 100.00 Nessuno

setsid 100.00 Nessunosetrlimit 100.00 Nessuno

gettimeofday 100.00 Nessunoreadlink 100.00 Nessunomunmap 100.00 Nessunofchmod 100.00 Nessuno

getpriority 100.00 Nessunosetpriority 100.00 Nessuno

statfs 100.00 Nessunofstatfs 100.00 Nessuno

Tabella 4.11: Codici di ritorno delle system call invocate nell’esperimento MEMORY boundcon SystemTAP/KProbes, primo gruppo.

Page 79: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 78

KProbes/SystemTAP – MEMORY BOUND – Codici di Ritorno – Parte 2Nome OK % Altri Codici

socketcall 099.99 ENOENT = 0.01wait4 050.00 ECHILD = 50fsync 100.00 Nessuno

sigreturn 048.69 EINTR = 51.31clone 100.00 Nessuno

newuname 100.00 Nessunomprotect 100.00 Nessuno

llseek 080.00 ESPIPE = 20getdents 100.00 Nessuno

select 100.00 Nessunowritev 100.00 Nessuno

nanosleep 100.00 Nessunopoll 056.50 EINTR = 43.5

rt sigaction 098.05 EINVAL = 1.95rt sigprocmask 100.00 Nessuno

getcwd 100.00 Nessunogetrlimit 100.00 Nessunommap2 100.00 Nessunostat64 099.76 ENOENT = 0.24lstat64 100.00 Nessunofstat64 100.00 Nessunogetuid 100.00 Nessunogetgid 100.00 Nessuno

geteuid 100.00 Nessunogetegid 100.00 Nessuno

setgroups 100.00 Nessunofchown 100.00 Nessunosetuid 066.67 EPERM = 33.33setgid 100.00 Nessuno

getdents64 100.00 Nessunofcntl64 100.00 Nessuno

futex 100.00 Nessunoset thread area 100.00 Nessuno

epoll wait 100.00 Nessuno

Tabella 4.12: Codici di ritorno delle system call invocate nell’esperimento MEMORY boundcon SystemTAP/KProbes, primo gruppo.

Page 80: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 79

Figura 4.4: PDF numero chiamate system call al secondo, caso MEMORY

4.2.1 Caso CPU bound

Come nel caso degli esperimenti di SystemTAP ci aspettiamo che il sistema stressato con unworlkload di tipo CPU bound non vada a sforzare particolarmete l’insieme delle system callin quanto le operazioni aritmetiche con cui e in effetti realizzato non richiedono dei “servizi”alle system call. Analizziamo quindi la pdf ottenuta attraverso il filtro e mostrata in figura4.5.

Come presupposto il numero di chiamate in un secondo non e molto elevato e la probabilitapiu alta e che questo numero sia compreso tra 1 e 25 chiamate. Da notare come l’andamentocomplessivo della pdf sia approssimabile anche in tal caso ad un esponenziale decrescente(cioe con base compresa tra 0 e 1). Ci sono comunque due piccole regioni corrispondentiad un numero di chiamate superiore a 70 in cui la probabilita e non nulla seppur moltobassa. Questi picchi lontani sono dovuti probabilmente alla natura ciclica del benchmark1

che periodicamente sforza il sistema in modo maggiore ma per breve durata; questo aspettosi riflette anche sul valor medio µ = 69.68 e sulla deviazione standard σ = 221.7. Valoritanto elevati di questi due parametri sono dovuti anche al fatto che, sempre a causa dellanatura del benchmark, in certi intervalli di un secondo vengono effettuati fino ad un massimodi 4419 chiamate come si evince dall’informazione relativa al massimo numero di chiamatein un secondo (Max) riportata anch’essa nel titolo del grafico. Naturalmente e molto bassala probabilita che in un secondo sia effettuato un numero cosı alto di chiamate e proprioper questo motivo si e deciso di fissare la massima ascissa rappresentabile a 150 onde noncomprimere troppo il grafico che presenta valori diversi da zero solo entro tale limite.

Analizziamo a questo punto i risultati relativi alla percentuale di chiamata delle singolesystem call. Applicato il filtro otterremo la figura 4.6 generata da gnuplot. Dal grafico risulta

1Oltre ai motivi gia ricordati nella sezione relativa a SystemTAP.

Armando Migliaccio
Note
vogliamo chiarirci un attimo su questo punto?
Page 81: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 80

Figura 4.5: Pdf delle chiamate ogni secondo nel caso CPU bound.

che oltre alle system call di I/O che risultano inevitabilmente invocate2 la system call piustressata e la rt sigaction che indubbiamente puo rientrare tra le system call maggiormentestressate da un worload CPU bound perche seve a gestire i segnali che si scambiano i processi.La system call brk che si occupa di ridimensionare i segmenti dati dei processi e invocatapochissime volte e questo e coerente con quanto ci si aspetta dal carico impiegato.

Resta infine da esaminare la situazione relativa ai codici di uscita delle singole system call.Tale informazioni vengono elencate nella tabella 4.13 ottenuta attraverso il filtro descritto nelcapitlo precedente e con la query mostrata nella sezione D.2.

Il significato dei codici di uscita viene mostrato nell’appendice E. Dalla tabella si evinceche la maggior parte delle chiamate termina a buon fine (alcune system call terminano semprecon successo) e solo una piccola percentuale termina in modo “anomalo”. Precisiamo che nonsi tratta di veri e propri insuccessi ma di situazioni particolari che possono ritenersi anchenella norma da certi punti di vista. La system call che termina con piu “variabilita” e di sicurola ioctl e questo non solo perche essa resta una di quelle piu invocate ma anche perche vieneusata per manipolare una miriade di caratteristiche operative relative ai file o ai device.

4.2.2 Caso IO bound

Utilizzando un workload che stressa il sistema di I/O e normale aspettarsi che il numero dichiamate alle system call fatte ogni secondo sia maggiore che nel caso in cui si usi un workloadche sforzi la CPU. Questa previsione e confermata dalla figura 4.7 che mostra la pdf relativaalle chiamate per secondo.

Rispetto al caso CPU bound la probabilita maggiore e che si abbiano tra le 20 e le 40chiamate in un secondo quindi quasi il doppio rispetto a prima. Inoltre la pdf, che ha in

2L’inevitabilita della loro invocazione e legata intrinsecamente al meccanismo di funzionamento di DSKIper cui si rimanda alla sezione 2.4.

Page 82: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 81

Figura 4.6: Percentuale di chiamata delle system call nel caso CPU bound.

ogni caso un andamento esponenziale decrescente, e piu distribuita lungo l’asse delle ascisseperche aumenta la probabilita che le chiamate possano essere in numero elevato mentre nelcaso CPU bound in molti intervalli la probabilita era proprio nulla. La media in tal casoraggiunge il valore µ = 219 mentre la deviazione standard arriva a σ = 536.8 e cio anchein conseguenza del fatto che il massimo numero di chiamate al secondo registrate stavoltaraggiunge addirittura le 5824 unita ben 1400 in piu di prima.

Analizziamo quindi il secondo grafico relativo alla percentuale di chiamata delle systemcall e mostrato in figura 4.8. Il grafico e perfettamente coerente con quanto ci si aspettaperche circa il 90% delle chiamate e distruibuito tra read, write e llseek ossia le principalisystem call di I/O.

La tabella 4.14 infine mostra i risultati relativi ai codici d’uscita. Anche in questo caso icodici sono piu o meno gli stessi e la system call con piu variabilita resta la ioctl nonostantenon sia, in questo caso, la piu invocata (e “solo” al quarto posto); e confortante pero il fattoche, come nell’esperimento IO bound gia descritto, le tre system call piu invocate termininosempre con successo (a parte qualche volta la llseek) e cio sicuramente riflette la natura“stabile” del kernel su cui sono stati eseguiti gli esperimenti.

4.2.3 Caso MEMORY bound

Il workload impiegato per stressare le system call che operano sulla memoria e descritto nellasezione 3.2.3 da cui si evince che esso e molto lineare in quanto non fa che chiedere memoriafinche non si comincia ad “intaccare” l’area di swap. Prima di mostrare i risultati ottenutibisogna rimarcare un aspetto estremamente importante. Come detto nella sezione 3.1 DSKIe ancora in fase sperimentale e si puo notare infatti che in particolari situazioni alcuni eventivengono persi nel senso che non arrivano al buffer seppur generati a livello kernel. Questasituazione accade in casi molto particolari e precisamente quando la frequenza con cui si

Page 83: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 82

ErrorName Name Occorrenze Totale PercRel PercAssOK SYS BRK 6876 6876 100.00 2.74OK SYS CLOSE 52961 56369 93.95 21.12EBADF SYS CLOSE 3408 56369 6.05 1.36OK SYS IOCTL 24166 32060 75.38 9.64EPERM SYS IOCTL 1 32060 0.00 0.00EAGAIN SYS IOCTL 240 32060 0.75 0.10EINVAL SYS IOCTL 3629 32060 11.32 1.45ENOTTY SYS IOCTL 424 32060 1.32 0.17EADDRNOTAVAIL SYS IOCTL 3600 32060 11.23 1.44OK SYS LLSEEK 895 896 99.89 0.36ESPIPE SYS LLSEEK 1 896 0.11 0.00OK SYS MMAP2 30878 30878 100.00 12.31OK SYS OPEN 21312 22100 96.43 8.50ENOENT SYS OPEN 738 22100 3.34 0.29ENXIO SYS OPEN 50 22100 0.23 0.02OK SYS READ 23348 23348 100.00 9.31OK SYS RT SIGACTION 48780 48786 99.99 19.45EINVAL SYS RT SIGACTION 6 48786 0.01 0.00OK SYS SELECT 5469 5469 100.00 2.18OK SYS WRITE 23985 23985 100.00 9.56

Tabella 4.13: Codici di uscita nel caso CPU bound.

ErrorName Name Occorrenze Totale PercRel PercAssOK SYS BRK 12 12 100.00 0.00OK SYS CLOSE 14007 14055 99.66 3.12EBADF SYS CLOSE 48 14055 0.34 0.01OK SYS IOCTL 10829 14275 75.86 2.41EAGAIN SYS IOCTL 112 14275 0.78 0.02EINVAL SYS IOCTL 1669 14275 11.69 0.37ENOTTY SYS IOCTL 1 14275 0.01 0.00EADDRNOTAVAIL SYS IOCTL 1664 14275 11.66 0.37OK SYS LLSEEK 115283 115371 99.92 25.65EINVAL SYS LLSEEK 87 115371 0.08 0.02ESPIPE SYS LLSEEK 1 115371 0.00 0.00OK SYS MMAP2 1858 1858 100.00 0.41OK SYS OPEN 3967 3976 99.77 0.88ENOENT SYS OPEN 7 3976 0.18 0.00ENXIO SYS OPEN 2 3976 0.05 0.00OK SYS READ 172009 172009 100.00 38.28OK SYS RT SIGACTION 4746 4746 100.00 1.06OK SYS SELECT 2460 2460 100.00 0.55OK SYS WRITE 120619 120619 100.00 26.84

Tabella 4.14: Codici di uscita nel caso IO bound.

Page 84: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 83

Figura 4.7: Pdf delle chiamate ogni secondo nel caso IO bound.

genera un evento e elevatissima. In tali casi, infatti, applicando al file binario un filtro dinarrazione si otterra un xml che elenca gli eventi catturati; ebbene i numeri che identificanogli eventi non sono tutti progressivi ma in alcuni punti ci sono dei vuoti. Ad esempio ci sonotutti gli eventi da 1 a 145 tranne qualcuno in mezzo. Il workload usato negli esperimentiMEMORY bound e per natura un workload insistente, che chiede continuamente memoriaquindi sicuramente devono essere catturati a livello kernel tantissimi eventi. Eseguendo ilworkload e stato possibile notare che, per i motivi appena indicati, molti eventi vengonoperduti. Questo fatto ci ha portato a cambiare leggermente il workload per ridurre il numerodi eventi generati. Naturalmente questo significa che i risultati dovranno essere interpretatiin maniera diversa per tentere conto di questo cambiamento. L’unica modifica apportata estata l’introduzione di una pausa tra una richiesta di 2.1 GB e la successiva (dopo il rilascioovviamente). In pratica si richiama la procedura usleep()3 che fa riposare il sistema perun certo numero di microsecondi. Il valore in questione e pari a 100000 µs ossia un decimodi secondo. In tal modo le richieste diventano meno insistenti e si perdono meno eventi.Data la natura del workload comunque ci si aspetta che il numero di system call invocate siaabbastanza costante in ogni secondo. La figura 4.9, che mostra la pdf nel caso in cui si utilizzitale carico, conferma pienamente ogni previsione in quanto la probabilita di avere un certonumero di chiamate al secondo e tutta concentrata tra 40 e 50 chiamate. L’andamento stavoltanon e simile ad un esponenziale descrescente ma si puo approssimare ad una gaussiana.Certamente il numero di chiamate che ha maggiore probabilita di occorerre e superiore aicasi esaminati in precedenza e questo e dovuto al fatto che il workload richiede in maniera“soffocante” memoria al sistema. Questa insistenza e pero molto continua in quanto il valormedio stavolta e pari a µ = 45.13 chiamate al secondo cioe e compreso nell’intervallo dei

3Si tenga presente che la chiamata di tale procedura non inquina i nostri risultati perche essa non richiamaalcuna system call tra le 10 monitorate con DSKI.

Page 85: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 84

Figura 4.8: Percentuale di chiamata delle system call nel caso IO bound.

valori che hanno la piu alta probabilita di capitare. Il valore della deviazione standard risultanettamente inferiore ai casi precedenti essendo pari solo a σ = 78.82 e anche il massimonumero di chiamate non supera le 2300 unita (2267 per l’esattezza). Se consideriamo lacurva come una normale possiamo allora affermare che con un fattore di copertura k = 3c’e il 99.7% delle probabilita che in un secondo il numero di chiamate stia nell’intervallo[1, 45 + 3 ∗ 78] ≈ [1, 280]4. In parole povere e rarissimo (0.3% delle probabilita) che in 1secondo vengano effettuate piu di 280 chiamate alle system call monitorate.

Confrontando la pdf con quella ottenuta nella sezione 4.1.3 si notera comunque che la nuovapdf e spostata verso sinistra cosı come si evince anche dal valor medio. Questa differenzae legata alla modifica apportata al workload ma si puo facilmente azzerare correggendo irisultati. Avendo inserito una pausa di un decimo di secondo, per avere risultati comparabili alcaso precedente bisogna considerare il numero di chiamate ogni 10 secondi. Allora applichiamoil filtro inserendo un intervalo di 10 secondi e non 1; il risultato e riportato nella figura 4.10.Il risultato mostrato stavolta e paragonabile a quello ottenuto nell’esperimento analogo conl’impiego di KProbes/SystemTAP. La media risulta µ = 449.3 e la deviazione standard eσ = 504.6 quindi valori vicini a quelli ottenuti in precedenza (526.74 e 621.7 rispettivamente).

Ma quale sara la system call piu invocata? La risposta ci viene fornita dalla figura 4.11 chemostra le percentuali di chiamata. Il premio della system call piu invocata stavolta spetta,come nell’esperimento MEMORY bound gia descritto, alla brk che copre circa il 22% deltotale. Questo e dovuto al fatto che il workload non fa altro che chiedere e rilasciare memoriae la brk svolge appunto l’operazione di allocazione (deallocazione) di memoria per i processiaumentando (diminuendo) il segmento dati relativo. Naturalmente la percentuale non arriva

4Matematicamente parlando l’intervallo dovrebbe essere approssimabile a [−191, 280] ma ovviamente l’e-sperimento non contempla un numero di chiamate non positivo quindi l’estremo sinistro deve essere posto a1.

Page 86: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 85

Figura 4.9: Pdf delle chiamate ogni secondo nel caso MEM bound.

ai valori dell’esperimento analogo gia eseguito ma questo non e dovuto al fatto che e stataapportata la modifica ma e legato alla natura del meccanismo di DSKI. Come precisato nellasezione 2.4 esso registra i dati su un dispositivo a caratteri quindi scrive su di esso mentreparallelamente il demone legge; questo spiega la percentuale di chiamata cosı alta delle systemcall di IO, anche in conseguenza del fatto che il carico genera tantissimi eventi e quindi siscrive tantissimo sul dispositivo. La tabella 4.15, infine, mostra i codici d’uscita ottenuti conil carico che stressa la memoria.

I valori ottenuti non differiscono molto dagli altri casi, segno che e normale che certeanomalie si verifichino; conforta ancora il fatto che la brk, la system call piu invocata, nontermini mai in modo anomalo.

4.3 Conclusioni

Da quanto mostrato nelle sezioni precedenti possiamo trarre alcune conclusioni riguardantinon solo i risultati delle chiamate alle system call ma anche riguardo all’impiego dei tool presiin considerazione.

Cominciamo proprio da quest’ultimo aspetto. I risultati ottenuti con i diversi tool nonsono assai dissimili segno che in linea di principio e perfettamente equivalente usare KPro-bes/SystemTAP o DSKI per strumentare i punti di interesse. Basandosi solo sui risultati,un qualunque programmatore potrebbe scegliere indifferentemente tra uno dei due strumenti.In realta abbiamo precisato che per il caso MEMORY bound e stato necessario modificareleggermente il workload a causa della perdita di alcuni eventi da parte dell’interfaccia. Questoaspetto e di sicuro un punto debole di DSKI perche non si puo affermare, nel caso in cui il ker-nel generi un numero elevatissimo di eventi (come nel caso MEMORY bound), che i risultatiassoluti sono veri. Normalizzandoli pero non ci dovrebbero essere differenze perche gli eventi

Page 87: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 86

Figura 4.10: Pdf delle chiamate ogni 10 secondi caso MEM bound.

persi si distribuiscono in maniera random per cui si perderanno in media 10 eventi di tipo Xe 10 di tipo Y e non 1 di tipo X e 19 di tipo Y. Questo discorso ovviamente puo essere evitatonel caso in cui gli eventi generati siano pochi perche si osserva facilmente che non si perdeneppure un evento. L’altro grande problema di DSKI, sempre limitandoci ai risultati ottenuti,e che esso e uno strumento molto piu invasivo di Kprobes/SystemTAP a causa del fatto chei dati catturati dal kernel debbono essere scritti in un buffer. Fintanto che si strumentanooperazioni diverse dalla read, write e simili, i risultati non vengono falsati ma nel momentoin cui ci si sofferma sul sottosistema di IO le percentuali vengono alterate. A parte questedue considerazioni evinte dai risultati non ci sono motivi per cui preferire uno strumento adun altro. Se invece osserviamo il procedimento di preparazione degli esperimenti sicuramenteDSKI risulta uno strumento abbastanza scomodo rispetto a KProbes/SystemTAP soprattut-to perche bisogna ricompilare il kernel. Certamente non e allo stesso livello della chiamatadella funzione printk perche rispetto a questa soluzione DSKI offre la possibilita di orga-nizzare logicamente i punti di strumentazione in famiglie e fornisce 5 categorie di entita distrumentazione (vedere sezione 2.2). Questo vantaggio in realta non e presente neppure neltool KProbes/SystemTAP ma in compenso il loro impiego non comporta la ricompilazionedel kernel. C’e poi un ultimo aspetto da considerare. Con DSKI abbiamo avuto la possibilitadi creare dei filtri appositi che hanno automatizzato tutto il procedimento di strumentazione;tali filtri inoltre sono riutilizzabili anche in altri contesti, alcuni senza modificare neppure unariga di codice. L’altro tool invece non offre nessun meccanismo di post–processing per cuideve essere onere del programmatore realizzare tutti i grafici e le tabelle!

Alla luce di tali considerazioni sarebbe interessante, in un futuro prossimo, fondere ivantaggi dell’uno e dell’altro strumento. In linea di principio bisogna capire come vienegenerato il file binario da parte del demone dski daemon; se si riesce a fare in modo cheKProbes/SystemTAP memorizzi le informazioni in tale formato, magari generando solo eventi

Page 88: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 87

Figura 4.11: Percentuale di chiamata delle system call nel caso MEMORY bound.

in cui i campi superflui (TimeStamp, Famiglia etc.) contengono valori di default, otterremmoun tool di strumentazione praticamente perfetto.

Per quanto riguarda invece il significato dei risultati ottenuti si puo concludere che essisono sufficientemente coerenti con quanto ci si aspettava in relazione al carico impiegatoper stressare il sistema. I risultati hanno messo in luce che la stragrande maggiornaza dellesystem call invocate termina con successo nel senso che la chiamata a sistema riesce a servirel’applicazione che ha richiesto il servizio. In una piccola percentuale di casi i valori di ritornosono negativi e cio vuol dire che i workload sono stati capaci di portare il sistema in unasituazione di limite e non e poco considerando che le versioni su cui gli esperimenti sono statieseguiti sono versioni stabili. I codici di uscita, che abbiamo chiamato codici d’errore anchese non si tratta di veri e propri errori, sono pressocche gli stessi nel caso del monitoraggiocon KProbes/SystemTAP o DSKI5. E’ interessante notare che in tutti gli esperimenti lasystem call che termina in modo piu variabile e sempre la ioctl e piu o meno restituiscegli stessi valori. Possiamo quindi affermare che effettivamente gli esperimenti posseggonocaratteristiche di stazionarieta, sono ripetibili e i risultati non dipendono dal tempo dellaloro durata (si ricordi che in DSKI l’esperimento e durato 1 ora e non 6). Se si decidessedi intervenire in qualche punto per migliorare la stabilita del sistema si potrebbe interveniresulla ioctl o comunque sui fattori che inducono la system call a terminare con una cosı altavariabilita e a tal scopo bisognerebbe cominciare studiando il significato dei codici d’uscitache abbiamo ottenuto negli esperimenti.

5L’unica differenza e che in DSKI abbiamo un sottoinsieme dei codici restituiti perche in realta e statostrumentato un sottoinsieme di system call.

Page 89: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

CAPITOLO 4. RISULTATI SPERIMENTALI 88

ErrorName Name Occorrenze Totale PercRel PercAssOK SYS BRK 36057 36057 100.00 22.29OK SYS CLOSE 32037 32073 99.89 19.81EBADF SYS CLOSE 36 32073 0.11 0.02OK SYS IOCTL 22959 30301 75.77 14.19EAGAIN SYS IOCTL 235 30301 0.78 0.15EINVAL SYS IOCTL 3542 30301 11.69 2.19ENOTTY SYS IOCTL 39 30301 0.13 0.02EADDRNOTAVAIL SYS IOCTL 3526 30301 11.64 2.18OK SYS LLSEEK 76 183 41.53 0.05ESPIPE SYS LLSEEK 107 183 58.47 0.07OK SYS MMAP2 8268 8268 100.00 5.11OK SYS OPEN 9988 11962 83.50 6.17ENOENT SYS OPEN 1963 11962 16.41 1.21ENXIO SYS OPEN 11 11962 0.09 0.01OK SYS READ 17577 17577 100.00 10.87OK SYS RT SIGACTION 10618 10618 100.00 6.56OK SYS SELECT 5245 5245 100.00 3.24OK SYS WRITE 9473 9473 100.00 5.86

Tabella 4.15: Codici di uscita nel caso MEMORY bound.

Page 90: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Appendice A

Installazione LibeRTOS/DSKI

Il framework di strumentazione di DSKI e allegato al particolare kernel LibeRTOS di cui eparte integrante, quindi per poterlo utilizzare e necessario disporre dei sorgenti di tale kernel.Per reperire tali sorgenti si faccia riferimento alla seguente URL:

http://viewcvs.ittc.ku.edu

oppure, se si dispone di un account presso la Kansas University, e possibile ottenerliutilizzando il seguente comando:

svn co https://subversion.ittc.ku.edu/svn/libertos/research/branches/2.6.12-RT-LIBERTOS

Il primo passo consiste nella compilazione del kernel. A tal scopo e necessario selezionare(o deselezionare) tra le opzioni di compilazione (eseguendo il comando make gconfig) alcunielementi come mostrato di seguito:

Code maturity level options||-[X]-Prompt for development and/or incomplete code/drivers

Processor type and features||-[ ]-Symmetric multi-processing support||--Preemption Mode

||-[X]-Preemptible kernel (Low-Latency Desktop)

Queste sono le opzioni di base necessarie per il funzionameto di DSKI/DSUI. Il kernelviene fornito con una serie di punti di strumentazione preinseriti nel codice. Per poterliabilitare e necessario eseguire il comando make dskifamilies e quindi scegliere le famiglieche si vuole siano abilitate tra quelle presenti nel menu seguente:

KU Libertos options||--KU Datastreams Kernel Interface

89

Page 91: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE A. INSTALLAZIONE LIBERTOS/DSKI 90

||--DSKI Family Configuration

||-- Famiglia 1|-- Famiglia 2|-- ......|-- Famiglia n-1|-- Famiglia n

Fatto cio bisogna compilare il kernel ed installarlo con i comandi

makemake modules_installmake install

In particolare il terzo comando avra come risultato quello di installare effettivamente ilkernel, preoccupandosi di spostarne l’immagine e la mappa di sistema nella directory /boot/e aggiornando il boot loader modificando il file /boot/grub/grub.conf. Per avviare il kernelsara sufficiente selezionarlo nell’elenco dei kernel installati mostrato all’avvio del sistema dalboot loader.

Per utilizzare appieno le funzionalita offerte, la suite di LibeRTOS si completa con ipacchetti kusp, kusp-doc, kusp-experiments. Tali pacchetti contengono, rispettivamente,le utility elencate nelle tabelle 1.1 e 1.2, la documentazione relativa e alcuni esempi chemostrano il funzionamento. Essi sono reperibili all’URL gia indicata in precedenza e inalternativa possono essere scaricati attraverso i comandi:

svn co https://subversion.ittc.ku.edu/svn/libertos/research/kusp

svn co https://subversion.ittc.ku.edu/svn/libertos/research/kusp-doc

svn co https://subversion.ittc.ku.edu/svn/libertos/research/kusp-experiments

Per poterli compilare e necessario avere a disposizione l’intero albero sorgente di LibeR-TOS.

La procedura per compilare kusp consiste nell’invocare, dalla directory in cui risiedono ipropri sorgenti, i seguenti comandi in successione:

./bootstrap

./configure --prefix=/usr --with-linuxsrc=<RootKernelLibeRTOS>

make

make install

Analogamente per compilare la documentazione kusp-doc invocare:

Page 92: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE A. INSTALLAZIONE LIBERTOS/DSKI 91

./bootstrap

./configure

make

make install

Infine per compilare gli esperimenti d’esempio di kusp-experiments invocare:

./bootstrap

./configure --with-kusproot=<RootKusp>

make

Dal momento che il kernel LibeRTOS si serve di un particolare dispoditivo a caratte-re per l’interfaccia DSKI/DSUI, come e specificato nella sezione 2.4, per poter eseguire unesperimento bisogna, all’avvio del sistema operativo, creare tale dispositivo con il seguentecomando:

# mknod /dev/dstream c 242 0

Page 93: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Appendice B

Ulteriori esempi

B.1 DSKI - Eventi per fork e alloc/free pages

L’esempio che segue copre in maniera piu articolata e generale i meccanismi gia toccati nel-l’esempio della sezione 2.3.3. Supponiamo che vogliamo avere informazioni sulla creazione dinuovi processi e sull’allocazione e deallocazione di pagine di memoria. Genereremo quindidue file *.ns che, per quanto detto nella sezione 2.1.2, debbono essere posti nella directo-ry <RootKernelLibeRTOS>/scripts/dski. Bisogna ricordare pero un aspetto importante:poiche tutti i file nella directory specificata definiscono un unico grande spazio dei nomi, econsiderando che quando si genera una nuova famiglia nello stesso spazio dei nomi il suo IDnon deve collidere con quello di un’altra, e consigliabile in questo caso avviare l’utility graficansedit e aprire tutti i file *.ns in modo da avere una visione complessiva degli ID e non doveraprire a mano uno per volta i vari file per evitare sovrapposizioni e quindi errori del parser.Creiamo quindi due file: pagetest.ns e forking.ns. Cominciamo dal file pagetest.ns:

#pagetest.ns

#!lib.parsers.ns_parser_v1namespace {

desc = ""family PAGE_FAM 25 {

desc = ""shortdesc = "Famiglia per strumentare

get e free pages."event PAGE_TRY_ALLOC 0 {

desc = ""kernelf = ""printf = "print_int"shortdesc = "Tentativo di allocare delle pagine."

}event PAGE_TRY_FREE 1 {

desc = ""kernelf = ""printf = "print_int"shortdesc = "Tentativo di deallocare delle pagine."

92

Page 94: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 93

}event PAGE_ALLOC_FROM 2 {

desc = ""kernelf = ""printf = "print_hex"shortdesc = "Allocate pagine a partire

dall’indirizzo dato."}event PAGE_DEALLOC_FROM 3 {

desc = ""kernelf = ""printf = "print_hex"shortdesc = "Dellocate pagine a partire

dall’indirizzo dato."}

}}

Il file definisce la famiglia PAGE FAM che contiene 4 eventi che svolgono il ruolo descrittodi seguito:

• PAGE TRY ALLOC cattura il tentativo di allocare un certo numero di pagine; il numero dipagine richieste verra considerato come dato extra di tipo intero (print int);

• PAGE TRY FREE cattura il tentativo di deallocare un certo numero di pagine; il numerodi pagine da rimuovere verra considerato come dato extra di tipo intero (print int);

• PAGE ALLOC FROM cattura l’effettiva allocazione delle pagine richieste in precedenza;l’indirizzo logico da cui comincia l’allocazione verra considerato come dato extra dastampare in esadecimale (print hex);

• PAGE DEALLOC FROM cattura l’effettiva deallocazione delle pagine richiesta in precedenza;l’indirizzo logico da cui comincia la deallocazione verra considerato come dato extra dastampare in esadecimale (print hex).

Il file forking.ns risulta invece:

#forking.ns

#!lib.parsers.ns_parser_v1namespace {

desc = ""family FORK_FAM 26 {

desc = ""shortdesc = "Famiglia per la fork"event DO_FORK 0 {

desc = "Cattura la chiamata della do_fork()e stampa il pid del processo."

Page 95: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 94

kernelf = ""printf = "print_pid"shortdesc = "Catturata la chiamata di do_fork()"

}}

}

Esso definisce la famiglia FORK FAM con l’evento DO FORK che inseriremo all’ingresso dellafork (in realta della do fork come preciseremo piu avanti). Tale evento cattura la chiamatadella funzione e porta con se l’informazione relativa al pid del processo figlio (per cui esegueuna print pid del dato extra che porta con se).

Da notare che gli identificativi delle famiglie sono 25 e 26 ossia due valori molto alti perchebisogna considerare che nella stessa directory ci sono gli altri namespace file che definisconoevidentemente altre 25 (si parte da 0) famiglie1. A questo punto si esegue il parsing ditutti i file *.ns e bisognera spostare i file generati in directory ben precise. Nella sezione2.3.3 abbiamo detto che e possibile invocare direttamente il comando make dskifamiliesma e necessario aggiungere al Makefile (precisamente alla label dskifamilies) il nome deidue file *.ns che abbiamo creato per passarli in ingresso al parser; aggiungiamo quindi -npagetest.ns e -n forking.ns. Invochiamo finalmente:

make dskifamilies

e automaticamente verranno generati i 4 file necessari e verranno spostati nelle opportuneposizioni come descritto nella sezione 2.1.2.

A questo punto andiamo a strumentare i punti di interesse. Per fare cio dobbiamo spenderequalche parola sulla funzione fork e su quella di allocazione delle pagine. Abbiamo dettoche vogliamo avere informazione sulla generazione di un processo e quindi, considerandoche in linux la fork() e la system call utilizzata per questa operazione, siamo interessati astrumentare il file fork.c che si trova in <RootKernelLibeRTOS>/kernel. In realta quellache strumenteremo non e la funzione fork() ma la do fork(...) che viene invocata diconseguenza a che a sua volta invoca altre funzioni come copy process() e simili. Inseriamoquindi al suo interno e precisamente alla fine, dove si ottiene il pid del processo figlio, la nostrariga di strumentazione:

...long pid = alloc_pidmap();...DSTRM_EVENT_FORK_FAM(DO_FORK, current->pid,

sizeof(long), (void*)&pid);

return pid;

Notiamo che l’extra dato sara costituito proprio dal pid del processo figlio e sara di tipolong perche cosı dichiarato in precedenza. L’altro campo della macro, ossia il tag simbolico perdiscriminare il verificarsi dello stesso evento, e il pid del padre. La posizione in cui abbiamoinserito il punto di strumentazione ovviamente ci permette di affermare che l’evento verra

1In realta nel kernel LibeRTOS le famiglie pre-inserite sono 21, le altre sono state inserite dall’utente.

Page 96: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 95

attraversato solo alla fine del processo di creazione e quindi un pid negativo indicherebbeche tale operazione non e andata a buon fine. Bisognerebbe poi includere nel file l’headerdatastream.h ma non e necessario perche gia e incluso in quanto usato nella sezione inizialedel sorgente.

Per quanto riguarda invece l’allocazione delle pagine, bisognera strumentare il sorgentepage alloc.c che si trova in <RootKernelLibeRTOS>/mm. Le funzioni che ci interessano sono:

unsigned long __get_free_pages(unsigned int __nocast gfp_mask,unsigned int order);

void __free_pages(struct page *page, unsigned int order);

La prima funzione viene invocata per richiedere un certo numero di pagine consecutive,precisamente 2order, con certe caratteristiche specificate dalla maschera e ritorna l’indirizzologico da cui parte l’allocazione.

La seconda funzione e quella che invece dealloca 2order pagine consecutive a partire dal-l’indirizzo della pagina fornita in ingresso. Considerando che siamo interessati ad avere infor-mazioni sul numero di pagine e non sull’ordine delle pagine, costruiamo una funzione ad hocche esegua il calcolo, dato che a livello kernel non possiamo sfruttare quella che viene messaa disposizione dalle librerie del C per non appesantire il codice. Definiamo quindi la seguenteprocedura che posizioniamo alla fine del file:

int totpages(int order){if (order == 0)

return 1;if (order == 1)

return 2;int var;var = 2;int k;k = 0;for(k=1; k<order; k++){

var *= 2;}return var;

}

Includiamo quindi il solito header datastream.h e strumentiamo le due funzioni. Ilrisultato sara il seguente:

...

fastcall unsigned long __get_free_pages(unsigned int __nocast gfp_mask,unsigned int order)

{int tot;tot = totpages(order);

Page 97: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 96

DSTRM_EVENT_PAGE_FAM(PAGE_TRY_ALLOC, current->pid,sizeof(int), (void*)&tot);

struct page * page;page = alloc_pages(gfp_mask, order);if (!page)

return 0;

DSTRM_EVENT_PAGE_FAM(PAGE_ALLOC_FROM, current->pid,sizeof(long), page_address(page));

return (unsigned long) page_address(page);}...

fastcall void free_pages(unsigned long addr, unsigned int order){

int tot;tot = totpages(order);DSTRM_EVENT_PAGE_FAM(PAGE_TRY_FREE, current->pid,

sizeof(int),(void*)&tot);

if (addr != 0) {BUG_ON(!virt_addr_valid((void *)addr));__free_pages(virt_to_page((void *)addr), order);

DSTRM_EVENT_PAGE_FAM(PAGE_DEALLOC_FROM, current->pid,sizeof(long), (void*)&addr);

}}

Notiamo che i due eventi il cui nome contiene la stinga TRY catturano effettivamente solo iltentativo di allocare o deallocare delle pagine e conservano come extra dato il numero effettivodi pagine mentre sono discriminati in base al pid del processo che invoca la funzione.

Gli altri due eventi invece sono posti alla fine delle funzioni per catturare l’effettiva allo-cazione e deallocazione e riportano come extra dato l’indirizzo logico da cui parte la primapagina allocata o deallocata rispettivamente. Questo indirizzo, per quanto detto in preceden-za, verra stampato in esadecimale benche non sia un indirizzo fisico; esso e esplicitamente pariall’argomento addr nella seconda funzione mentre nella prima deve essere ottenuto dalla chia-mata di page address(page) che opera oportunamente sul campo virtual della strutturapage definita in mm.h che risiede in <RootKernelLibeRTOS>/include/linux.

Concluso questo passo, eseguiamo il comando make gconfig dalla radice del kernel eselezioniamo le nostre due famiglie PAGE FAM e FORK FAM tra quelle disponibili in:

KU Libertos options|

Page 98: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 97

|--KU Datastreams Kernel Interface||--DSKI Family Configuration

||-- Famiglia 1|-- Famiglia 2|-- ......|-- Famiglia n-1|-- Famiglia n

A questo punto eseguiamo in successione i tre comandi di compilazione ed installazione:

make

make modules_install

make install

Quindi riavviamo il sistema. Adesso e possibile eseguire l’esperimento. Innanzitutto de-finiamo un file di abilitazione degli eventi che vogliamo monitorare, chiamiamolo ad esempiopagfork.dski. Abilitiamo tutti gli eventi delle due famiglie, scegliamo una durata dell’espe-rimento pari a 5 secondi, settiamo la frequenza a 1 quindi, scegliamo il nome del file binarioin cui salvare le informazioni e forniamo i 2 namespace file forking.ns e pagetest.ns. Ilrisultato sara il seguente:

#pagfork.dski#!lib.parsers.expt_parser_v1

EXPERIMENT_DURATION 5

# Snapshot Frequency

SNAPSHOT_FREQUENCY 1

# Binary Target

BINARY_TARGET "pagfork.bin"

# Namespace File

NAMESPACE_FILE "usr/src/2.6.12-RT_LIBERTOS/script/dski/pagetest.ns"

NAMESPACE_FILE "usr/src/2.6.12-RT_LIBERTOS/script/dski/forking.ns"

# Enabled Entities

Page 99: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 98

DSTRM_EVENT PAGE_FAM 25 PAGE_TRY_ALLOC 0DSTRM_EVENT PAGE_FAM 25 PAGE_DEALLOC_FROM 3DSTRM_EVENT PAGE_FAM 25 PAGE_ALLOC_FROM 2DSTRM_EVENT PAGE_FAM 25 PAGE_TRY_FREE 1DSTRM_EVENT FORK_FAM 26 DO_FORK 0

Avviamo l’esperimento con il comando

dski_daemon -e pagfork.dski

ricordandoci di far partire un paio di applicazioni durante il monitoraggio onde catturarela chiamata di qualche do fork(). Si potra notare dopo 5 secondi il file binario pagfork.bincon i dati da interpretare. Costruiamo a questo punto il solito filtro di narrazione degli eventispecificando, magari attraverso l’utility grafica filterconfig, tutte le informazioni necessarieal post–processing. Quello che si ottiene e il seguente file che chiamiamo filtro1.filter:

# filtro1.filter# DTD PATH

dtd_path = /usr/share/kusp/dtds

# Input File(s)

input_file:pagfork.bin # filenamebinary # file type# namespaces:usr/src/2.6.12-RT_LIBERTOS/script/dski/pagetest.nsusr/src/2.6.12-RT_LIBERTOS/script/dski/forking.ns

# Output_file

output_file:filtro1.xml # filenamexml # file type# namespaces:

# utility.narrate filter

filter utility.narrate {namespaces = [usr/src/2.6.12-RT_LIBERTOS/script/dski/pagetest.ns

usr/src/2.6.12-RT_LIBERTOS/script/dski/forking.ns]}

Eseguiamo quindi il comando

dstream_filter.py -c filtro1.filter

Page 100: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 99

e otterremo cosı il file narration.txt e filtro1.xml. Come ci aspettiamo, il file dinarrazione elenca la cronologia degli eventi catturati come mostra il seguente frammento:

+1.272 PAGE_TRY_FREE: Tentativo di deallocare delle pagine.+0.385 PAGE_DEALLOC_FROM: Dellocate pagine a partire dall’indirizzo dato.+66.511 PAGE_TRY_FREE: Tentativo di deallocare delle pagine.+0.541 PAGE_DEALLOC_FROM: Dellocate pagine a partire dall’indirizzo dato.

+118.188 PAGE_TRY_ALLOC: Tentativo di allocare delle pagine.+0.633 PAGE_ALLOC_FROM: Allocate pagine a partire dall’indirizzo dato.+2.921 DO_FORK: Catturata la chiamata di do_fork.

+1121.137 DO_FORK: Catturata la chiamata di do_fork.+2110.372 PAGE_TRY_FREE: Tentativo di deallocare delle pagine.

+0.877 PAGE_DEALLOC_FROM: Dellocate pagine a partire dall’indirizzo dato.+33.721 PAGE_TRY_ALLOC: Tentativo di allocare delle pagine.+0.735 PAGE_ALLOC_FROM: Allocate pagine a partire.

Come sempre i tempi indicati sono gli intervalli che trascorrono tra il verificarsi di unevento e il successivo. Se vogliamo esaminare pero anche gli extra dati e necessario fareriferimento al file filtro1.xml di cui mostriamo alcune righe:

<ENTITY number="1819" tag="5679" time_stamp="33501586810994"clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="PAGE_TRY_ALLOC" family="PAGE_FAM" id="1600" ><EXTRA_DATA format="base64">AQAAAA==</EXTRA_DATA><EXTRA_DATA format="custom">Value = 1.000000

</EXTRA_DATA></EVENT></ENTITY><ENTITY number="1820" tag="5679" time_stamp="33501586812678"

clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="PAGE_ALLOC_FROM" family="PAGE_FAM" id="1602" ><EXTRA_DATA format="base64">AAAAAA==</EXTRA_DATA><EXTRA_DATA format="custom">HEX = 0X0

</EXTRA_DATA></EVENT></ENTITY><ENTITY number="1821" tag="5678" time_stamp="33501586820446"

clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

Page 101: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 100

<EVENT name="DO_FORK" family="FORK_FAM" id="1664" ><EXTRA_DATA format="base64">LxYAAA==</EXTRA_DATA><EXTRA_DATA format="custom">pid = 5679</EXTRA_DATA></EVENT></ENTITY><ENTITY number="1822" tag="5678" time_stamp="33501589802210"

clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="DO_FORK" family="FORK_FAM" id="1664" ><EXTRA_DATA format="base64">MBYAAA==</EXTRA_DATA><EXTRA_DATA format="custom">pid = 5680</EXTRA_DATA></EVENT></ENTITY><ENTITY number="1823" tag="2596" time_stamp="33501595414930"

clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="PAGE_TRY_FREE" family="PAGE_FAM" id="1601" ><EXTRA_DATA format="base64">AQAAAA==</EXTRA_DATA><EXTRA_DATA format="custom">Value = 1.000000

</EXTRA_DATA></EVENT></ENTITY><ENTITY number="1824" tag="2596" time_stamp="33501595417262"

clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="PAGE_DEALLOC_FROM" family="PAGE_FAM" id="1603" ><EXTRA_DATA format="base64">ALCV2g==</EXTRA_DATA><EXTRA_DATA format="custom">HEX = 0Xda95b000

</EXTRA_DATA></EVENT></ENTITY>

Le righe fanno riferimento ad una parte dell’insieme degli eventi elencati in precedenzadal file narration.txt. Si puo notare la creazione di 2 processi da parte del processo con pid2678 nonche la richiesta di allocare prima e deallocare dopo una pagina di memoria (anche se

Page 102: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 101

la pagina deallocata nella seconda parte non e la stessa allocata in precedenza come si evincedall’indirizzo logico diverso espresso in esadecimale)2.

B.2 DSKI - Contatori strumentando un modulo

Per chiudere la trattazione sugli esempi per DSKI si ritiene utile fornire un esempio che facciauso dei contatori e che riguardi la strumentazione di un sorgente relativo ad un modulo delkernel. Supponiamo che vogliamo monitorare l’evento di creazione di una directory su unapartizione vfat3 e contare quante volte tale evento si verifica. Cominciamo dal solito file dellospazio dei nomi che chiamiamo mkdir.ns:

#mkdir.ns#!lib.parsers.ns_parser_v1namespace {

desc = ""family MKDIR_FAM 27 {

desc = ""shortdesc = "Famiglia make directory"event FAT_MAKE 0 {

desc = ""kernelf = ""printf = "print_string"shortdesc = "Cattura un make su fat."

}counter MK_CNT 0 {

desc = ""kernelf = ""printf = ""shortdesc = "Conta i make dir."

}}

}

Abbiamo quindi definito la famiglia MKDIR FAM e in essa l’evento FAT MAKE e il contatoreMK CNT. L’evento in particolare esegue una print string perche si vuole estrarre come extradato il nome della directory creata. Si riesegue quindi la procedura di parsing gia espostanell’esempio precedente. Restano da inserire i punti di strumentazione. Consideriamo quindiil file namei.c che si trova nella directory <RootKernelLibeRTOS>/fs/vfat. In esso vieneimplementata la funzione

static int vfat_mkdir(struct inode *dir, struct dentry *dentry, int mode)

che viene per l’appunto invocata quando si crea una nuova directory. Quindi includiamol’header datastream.h e inseriamo alla fine della stessa funzione le seguenti righe per lastrumentazione:

2E’ interessante notare che non viene praticamente mai fatta una richiesta di pagine che superi l’unita.3Vfat e proprio il nome del modulo che consente di operare su una partizione di questo tipo e che solitamente

viene caricato all’avvio del sistema.

Page 103: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 102

....DSTRM_EVENT_MKDIR_FAM(FAT_MAKE, current->pid,

sizeof(char)*DNAME_INLINE_LEN_MIN,(void*)dentry->d_name.name);

DSTRM_ADD_TO_COUNTER_MKDIR_FAM(MK_CNT, 1);return 0;

Si noti che i due punti di strumentazione vengono effettivamente attraversati solo quandotutto va a buon fine e si crea la directory (solo in quel caso infatti viene restituito il valore0). L’evento FAT MAKE ha come tag il pid del processo che invoca la make e logga come datoextra il nome della directory che viene recuperato dal parametro dentry di tipo dentry edefinito in d cache.h, secondo la gerarchia dentry->d name.name. Il valore della costanteDNAME INLINE LEN MIN definisce il numero minimo di caratteri messi a disposizione per ilnome di una directory quindi la dimensione dell’extra dato deve essere per forza pari a quelladi un carattere moltiplicato per questo valore (in genere pari a 36). Il secondo punto distrumentazione serve ad incrementare il contatore di un unita. In questo caso, a differenzache in DSUI, non e necessario resettare o loggare esplicitamente il valore del contatore perchesono operazioni fatte di default dalla piattaforma.

A questo punto si rieseguono gli stessi passi descritti in precedenza per quello che riguar-da configurazione, compilazione ed installazione. Riavviato il sistema si definisce il file diabilitazione delle entita che chiamiamo vfat.dski in cui abilitiamo il contatore e l’evento edefiniamo tra l’altro un esperimento della durata di 10 secondi. Eseguiamo quindi il comando

dski_daemon -e vfat.dski

e contemporaneamente invochiamo i seguenti comandi su una partizione formattata vfat:

mkdir sabatomkdir domenica

Dopo 10 secondi verra generato il file binario a cui applicheremo il nostro solito filtrochiamato filtro1.filter attraverso il comando

dstream_filter.py -c filtro1.filter

Non ci rimane che esaminare il file .xml generato e che e mostrato di seguito:

<ENTITY number="1" tag="3081" time_stamp="11044586296970"clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="FAT_MAKE" family="MKDIR_FAM" id="1728" ><EXTRA_DATA format="base64">c2FiYXRvAABhdGUub3JpZwD//wD///8A////AP///wD///8A</EXTRA_DATA><EXTRA_DATA format="custom">sabato</EXTRA_DATA></EVENT>

Page 104: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 103

</ENTITY><ENTITY number="2" tag="3082" time_stamp="11044589282294"

clock_id="localhost.localdomain"time_std="0" type="EVENT" conv_ts="0" low_err="0" high_err="0" >

<EVENT name="FAT_MAKE" family="MKDIR_FAM" id="1728" ><EXTRA_DATA format="base64">ZG9tZW5pY2EAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA</EXTRA_DATA><EXTRA_DATA format="custom">domenica</EXTRA_DATA></EVENT></ENTITY><ENTITY number="3" tag="0" time_stamp="11047105302422"

clock_id="localhost.localdomain"time_std="0" type="COUNTER" conv_ts="0" low_err="0" high_err="0" >

<COUNTER name="MK_CNT" family="MKDIR_FAM" id="1728" count="2"first_updatetime="11044586301930" last_updatetime="11044589285190"/>

</ENTITY>

E’ facile osservare che le due creazioni di directory sono state catturate perfettamente ene viene mostrato anche il nome. Inoltre il valore del contatore, in seguito alle chiamate dimkdir, ha raggiunto il valore 2 come ci si aspettava4.

Ci si pone a questo punto una domanda. Considerando il concetto stesso di modulo epossibile strumentarne uno senza dover ricompilare tutto il kernel? La risposta e parzialmentesı. Infatti se si decide in qualunque momento di strumentare un modulo usando delle famiglieche gia sono state configurate nel kernel5 allora e sufficiente ricompilare solo il modulo. Seviceversa si decide di utilizzare nuove famiglie allora non c’e soluzione e bisognera ricompilaretutto. In definitiva quindi nel momento in cui si decide di introdurre (e di usare) anche unsemplice nuovo evento sara necessaria la ricompilazione del kernel6.

B.3 DSUI - Intervalli

Lo scopo dei questa sezione e di fornire un esempio d’uso dell’entita “intervallo” definita nellasezione 2.2.3. Per fare cio ci proponiamo di usare l’interfaccia DSUI, ma nulla cambia se siutilizza DSKI7. Cominciamo, come al solito, dal nostro file dello spazio dei nomi che abbiamochiamato interval.ns:

4Facciamo pero due precisazioni. Innanzitutto e probabile che molti editor non consentano di leggere il filexml a causa della rappresentazione delle stringhe “domenica” e “sabato” in base 64 (formattazione di default).Poi evidenziamo che il file xml presenta ulteriori righe che riportano di nuovo il valore del contatore. Questovalore pero non rimane pari a 2 ma ritorna a zero, probabilmente perche il contatore si resetta ogni volta chela piattaforma va a leggerlo.

5Il che significa che sono stati creati tutti i file *.ns, e stato eseguito il parsing ed e stata fatta almeno unavolta la compilazione del kernel.

6Una soluzione potrebbe essere quella di creare all’inizio una serie di famiglie con eventi, contatori etc. chenon saranno usati al momento ma che potranno essere di appoggio per casi futuri. Una volta ricompilatoil kernel essi saranno utilizzabili in qualunque momento e non sara richiesta alcuna ulteriore ricompilazione(ammesso che ovviamente si strumenti un modulo).

7A parte il fatto di dover ricompilare il kernel!

Page 105: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 104

#!lib.parsers.ns_parser_v1namespace {

desc = ""family EVENTI_FAM 1 {

desc = ""shortdesc = "Famiglia per gli eventi"event EVENTO_START 0 {

desc = ""kernelf = ""printf = ""shortdesc = "Evento di partenza"

}event EVENTO_END 1 {

desc = ""kernelf = ""printf = ""shortdesc = "Evento di arrivo"

}}family INTERVALLI_FAM 2 {

desc = ""shortdesc = "Famiglia per gli intervalli"interval INTERVALLO_INT 0 {

desc = ""kernelf = ""printf = ""shortdesc = "Itervallo start-end"

}}

}

Nel file e stata definita una famiglia (EVENTI FAM) che contiene i due eventi che utilizzeremoper definire gli estremi dell’intervallo; da notare che i due eventi EVENTO START ed EVENTO ENDsono eventi semplici che non loggano alcun tipo di extra dato (come si evince dal fatto che none specificata alcuna funzione di print) ma non e obbligatorio che sia cosı. La seconda famiglia,INTERVALLI FAM, serve invece per contenere l’intervallo INTERVALLO INT che utilizzeremo. Aquesto punto bisogna eseguire il solito parsing col comando:

dsui-parse.py -n interval.ns -t interval

Da cio si otterranno i soliti tre file:

interval_dsui_families.hinterval_dsui_table.hinterval_dsui_vars.h

Adesso bisogna decidere cosa vogliamo strumentare e stabilire quale intervallo di tempoe di nostro interesse. A tal scopo, per fornire un esempio che mostri il calcolo della durata di

Page 106: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 105

un intervallo in maniera che l’utente possa avere un riscontro reale di cio che viene calcolato,facciamo riferimento al seguente file interval.c:

#include <stdio.h>

#ifdef ENABLE#define CONFIG_DSUI#define CONFIG_DSTREAM_EVENTI_FAM

#endif

#include <dsui.h>#include "interval_dsui_table.h"

int main(){

// Inizializzazione della piattaformaDSUI_INIT("interval.bin","interval.dsui");

printf("Questa e’ una prova\n");int j = 0;int valore[10];

for(; j< 10; j++){// Parte l’intervalloDSTRM_EVENT_EVENTI_FAM(EVENTO_START, 0, 0, NULL);

printf("Inserire un intero...");scanf("%d", &valore[j]);

// Termina l’intervalloDSTRM_EVENT_EVENTI_FAM(EVENTO_END, 0, 0, NULL);

}

// Terminazione della piattaformaDSUI_CLEANUP;return 0;

}

Il codice e molto semplice: il nostro intervallo e banalmente il tempo che passa tra l’i-stante in cui l’utente riceve a video la stringa Inserire un intero... e l’istante in cuieffettivamente inserisce l’intero. Il ciclo for e stato inserito proprio per avere la possibilita dimisurare piu volte l’intervallo di tempo che, si presume, avra valori diversi ogni volta perchela sua durata dipende dall’utente.A questo punto creiamo il nostro file di abilitazione interval.dsui:

#!lib.parsers.expt_parser_v1

Page 107: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 106

DSTRM_EVENT EVENTI_FAM 1 EVENTO_END 1DSTRM_EVENT EVENTI_FAM 1 EVENTO_START 0

E’ facile osservare che l’intervallo non va abilitato perche non avrebbe senso visto chenon esiste nessuna macro relativa ad esso che gli consenta di salvare informazioni. Fatto ciocompiliamo il tutto col comando:

gcc interval.c interval_dsui_vars.c -o intervalexe -ldsui -DENABLE

dove viene usato il solito trucco per abilitare tutte le famiglie. Si ottiene quindi il fileeseguibile intervalexe. Esso va lanciato e a questo punto e possibile sbizarrirsi a piacereinserendo i valori interi ad intervalli di tempo variabile. Alla fine sara possibile ottenere il fileinterval.bin che ci interessa.

Figura B.1: Filtro di conversione

A questo punto entra in gioco la fase di post–processing dei dati. Per poter visualizzareun grafico relativo all’intervallo e necessario eseguire un filtraggio doppio. Innanzitutto, at-traverso l’utiliti filterconfig, una volta caricate tutte le informazini necessarie (file binario,namespace file...), scegliamo il filtro conversion.interval. Aggiungiamo il filtro come dafigura B.1. La finestra consente a questo punto di definire tutte le informazioni utili perl’intervallo a cominciare proprio dagli eventi che hanno il ruolo di “estremi” dell’intervallo.Inseriamo quindi i valori come mostrato e salviamo il tutto come filtro1.filter8. Da no-

8Precisiamo che il file di output in cui verra posto il risultato del filtraggio, e che va specificato nel tab“I/O”, e stato chiamato filtro1.xml.

Page 108: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 107

tare che non abbiamo inserito alcun nome di processo in quanto nel nostro caso i punti distrumentazione sono attraversati sempre dallo stesso processo (intervalexe). Applichiamoquindi il filtro attraverso il comando

dstream_filter.py -c filtro1.filter

Figura B.2: Filtro di creazione dati

che generera il file filtro1.xml che andra filtrato ancora. Quindi riavviamo l’utilityfilterconfig e stavolta scegliamo come file di input non il file binario bensı l’xml ottenutodal passo precedente. L’inclusione dell’xml fa sı che non sia piu necessario specificare il filedello spazio dei nomi. Il filtro da selezionare questa volta e chiamato (a buon motivo)interval.interval histogram graph e va riempito cosi come da figura B.2. I dati da inse-rire, oltre alle semplici label e al titolo, riguardano la frequenza del processore su cui si eseguel’esperimento, il nome dell’intervallo, l’unita in cui misurare l’intervallo, e i valori minimoe massimo che se impostati a zero verranno selezionati in automatico. In qualche caso puoessere utile mostrare l’asse delle ordinate in scala logaritmica; nel nostro caso l’opzione non

Page 109: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 108

serve (come mostra la scelta del campo impostato a “no”). Una volta inserite le informazionisalviamo il tutto come filtro2.filter e avviamo il classico comando

dstream_filter.py -c filtro2.filter

Cio porta alla generazione di due file:

• INTERVALLO INT commands.gnuplot che contiene i comandi per la generazione e laformattazione di un’immagine *.ps che mostra il grafico;

• INTERVALLO INT data.dat che contiene i dati veri e propri che definiscono le barre delgrafico.

A questo punto non rimane che eseguire il comando

gnuplot INTERVALLO_INT_commands.gnuplot

e verra cosı generata l’immagine INTERVALLO INT.ps mostrata nella figura B.3.L’istogramma dimostra che sono state fatte tre immissioni di input in meno di 1 secondo,

2 in un tempo tra 1.8 e 2.4 (circa) secondi e le altre in tempi minori o maggiori ma sparsi.Mediamente l’utente ha inserito qualcosa ogni 2.3 secondi.

Page 110: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE B. ULTERIORI ESEMPI 109

Figura B.3: Istogramma

Page 111: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Appendice C

Filtri

In questa sezione vengono descritti i 3 filtri impiegati per il post-processing dei risultatisperimentali ottenuti tramite la strumentazione con DSKI.

C.1 Il filtro event pdf

Il filtro in questione, come gia accennato nella sezione 3.5.1 serve per tracciare la pdf delnumero di chiamate di una system call in un certo intervallo di tempo (nell’esperimentoimpostato a 1 s) nonche ottenere la media e la deviazione standard dei valori tracciati. Perfare cio il filtro si appoggia all’applicazione octave (che a sua volta si appoggia a gnuplot) pergenerare l’immagine desiserata. Il filtro deve quindi contare il numero di chiamate in un certointervallo di tempo e salvare questa informazione in un file dati che poi servira all’applicazioneper eseguire il plottaggio. Onde automatizzare tutto il processo di generazione dell’immagineviene prodotto anche il file che contiene i comandi per l’applicazione octave. Analizziamoquindi le 3 sezioni fondamentali.

C.1.1 Definizione e costruttore

Cominciamo col fornire il codice che riguarda la definizione della classe e il costruttore:

class event_pdf_filter(filter_framework.abstract_filter):"""Conta gli eventi verificatisi nell’intervallo di tempo specificatoe genera un grafico con la pdf relativa.Universita degli studi di Napoli Federico IICristofaro Gozzolino - Paolo Guadagnuolo"""

def __init__(self, parameters, _input=None, _output=None):

filter_framework.abstract_filter.__init__(self, _input, _output)

self.read = 0

110

Page 112: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE C. FILTRI 111

self.start = 0self.n = 0self.values = [0]self.factor = 0

self.machineticks = parameters["machineticks"]self.interval = parameters["interval"]self.buckets = parameters["buckets"]self.rangemax = parameters["xrangemax"]self.xtics = parameters["xtics"]self.extension = parameters["extension"]self.outdat = parameters["outdat"]self.outimg = parameters["outimg"]pass

expected_parameters = {"interval":{"type":const().PARAM_REAL, "order":10,

"doc":"Dimensione Intervallo", "default":1},"buckets":{"type":const().PARAM_INT, "order":20,

"doc":"Numero di Buckets", "default":15},"xrangemax":{"type":const().PARAM_INT, "order":30,

"doc":"Estremo superiore asse x"},"xtics":{"type":const().PARAM_INT, "order":40,

"doc":"Unita di rappresentazione delle tacche sull’asse x"},"extension":{"type":const().PARAM_STRING, "order":50,

"doc":"Formato Immagine (ps|png)","default":"png"},"outdat":{"type":const().PARAM_STRING, "order":60,

"doc":"Nome del file di dati (*.dat)"},"outimg":{"type":const().PARAM_STRING, "order":70,

"doc":"Nome del file immagine di uscita"},"machineticks":{"type": const().PARAM_LONG, "order":1,

"doc":"Ticks per secondo del processore"}}

Osserviamo innazitutto che il filtro riceve in ingresso una moltitudine di parametri; moltiservono semplicemente ad impostare le opzioni relative all’immagine (range dei valori, tacchedell’asse, nome dell’immagine, estensione...). I parametri fondamentali sono invece intervale machineticks. Essi sono indispensabili affinche il metodo di processazione possa operarein quanto definiscono, rispettivamente, la durata dell’intervallo su cui contare le chiamate ela velocita della macchina in numero di tick del processore. Le altre variabili membro sonoinvece semplici variabili di supporto al metodo analizzato nella sezione successiva.

C.1.2 Il metodo process

Di seguito e riportato il metodo fondamentale di processazione:

Page 113: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE C. FILTRI 112

def process(self, entity):""" Questa funzione effettua il processing """

if(self.read == 0):self.start = entity.getTime_stamp()self.read = 1self.values[self.n] = 1self.factor = float(float(self.interval)*self.machineticks)

if(entity.getTime_stamp() < (self.start + (self.n+1)*self.factor)):self.values[self.n] += 1

else:offset = entity.getTime_stamp() - (self.start +

(self.n+1)*self.factor)nintpassed = int(offset / (self.factor))if(nintpassed != 0):

for x in range(1, nintpassed):self.n += 1self.values += [0]

self.n += 1self.values += [1]

pass

Il metodo di processazione e quello che deve effettivamente contare le chiamate in ogniintervallo. A tal proposito la variabile values e la lista che contiene i valori relativi a ciascunintervallo per cui dovra successivamente essere fornita in output dal filtro. Ricordiamo cheil metodo process viene eseguito una volta per ogni entita incontrata nel file binario ininput per cui la variable read serve appunto per discriminare il caso in cui il metodo vengaeseguito la prima volta (in tal caso e necessaria una inizializzazione che non si puo eseguirenel costruttore perche bisogna accedere alle entita) e i casi successivi. L’informazione fornitadal numero di tick del processore viene utilizzata perche, onde dividere il tempo in intervalli,viene usata l’informazione di TimeStamp associata a ciascuna entita. Il TimeStamp e pero injiffies, come precisato nella tabella 2.1, quindi bisogna trasformarlo in secondi da cui l’esigenzadi conoscere la frequenza del clock. Per memorizzare l’informazione desiderata si confronta ilTimeStamp con l’estremo superiore dell’intervallo in cui si sta lavorando; se il TimeStamp einferiore allora si incrementa l’elemento nella lista values altrimenti ci si sposta all’intervallosuccessivo aggiungendo un nuovo elemento alla lista.

C.1.3 Il metodo close

Quella che segue e l’impementazione del metodo di terminazione close:

def close(self):outfiledat = file(self.outdat+".dat", ’w’)for x in self.values:

if (x != 0):outfiledat.write(str(x))

Page 114: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE C. FILTRI 113

outfiledat.write(’\n’)outfiledat.flush()outfiledat.close()

outfilem = file(’Commands.m’, ’w’)

if(self.extension == "ps"):outfilem.write(’gset terminal postscript landscape 12;\n’)ext = ".ps"

else:outfilem.write(’gset terminal png;\n’)ext = ".png"

outfilem.write(’gset xrange [1:%d];\n’ % self.rangemax)outfilem.write(’gset xtics %d\n’ % self.xtics)outfilem.write(’gset output \"%s\";\n’ % (self.outimg+ext))outfilem.write(’gset key off;\n’)outfilem.write(’x = load(\’%s\’);\n’ % (self.outdat+".dat"))outfilem.write(’s = ["PDF degli eventi - Media = ",

num2str(mean(x))," Deviazione standard = " ,num2str(sqrt(var(x))), " Max = ", num2str(max(x))];\n’)

outfilem.write(’title(s);\n’)outfilem.write(’xlabel(\’Numero di occorrenze ogni %f sec\’);\n’

% float(self.interval))outfilem.write(’t=hist(x,%d,1);\n’ % self.buckets)outfilem.write(’asse=[1:max(x)/%d:max(x)];\n’ % self.buckets)outfilem.write(’if (length(asse)>length(t))\n’)outfilem.write(’\tplot(asse(1:%d),t);\n’ % self.buckets)outfilem.write(’elseif (length(asse)<length(t))\n’)outfilem.write(’\tplot(asse,t(1:length(asse)));\n’)outfilem.write(’else\n\tplot(asse,t);\nend’)outfilem.flush()outfilem.close()pass

Questo metodo viene richiamato alla fine della processazione ed esegue le semplici operazioniche portano alla generazione del file dati e del file di comandi da fornire ad octave. Essoquindi non fa altro che aprire due file, scriverci sopra e poi chiuderli. Sara onere dell’utentepassare successivamente i comandi all’applicazione per ottenere l’immagine finale. Si notiche l’informazione relativa alla media e alla deviazione standard viene mostrata nel titolodell’immagine e i relativi valori sono calcolati non dal filtro ma dall’applicazione octave coni comandi di mean() e var(). In aggiunta, viene fornita anche l’indicazione del massimonumero di chiamate fatte nell’intervallo di tempo specificato, informazione assai utile perconsentire una corretta interpretazione degli altri due valori.

Page 115: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE C. FILTRI 114

C.2 Il filtro event percent

Tale filtro viene utilizzato per ottenere un grafico a barre in cui ogni barra corrisponde aduna system call e la relativa altezza equivale alla percentuale di chiamata della system callassociata. Anche in tal caso, come per il filtro visto nella sezione precedente, vengono fornitidei file di uscita che memorizzano le informazioni da plottare e i comandi da utilizzare. Inquesta circostanza ci appoggiamo direttamente all’applicazione gnuplot a causa della naturadel grafico da realizzare.

C.2.1 Definizione e costruttore

Forniamo di seguito la definizione della classe ed il relativo costruttore:

class event_percent_filter(filter_framework.abstract_filter):"""Il filtro genera grafici riguardo al numero di chiamate ee’ possibile inoltre fornire alcuni parametri per settarele impostazioni riguardo alla formattazione del graficoin output.Universita degli studi di Napoli Federico IICristofaro Gozzolino - Paolo Guadagnuolo

"""

def __init__(self, parameters, _input=None, _output=None):

filter_framework.abstract_filter.__init__(self, _input, _output)

self.sys_name = parameters["sys_name"]self.files_path = parameters["files_path"]self.figura_ext = parameters["figura_ext"]self.figura_name = parameters["figura_name"]self.trama_bars = parameters["trama_bars"]self.log_y = parameters["log_y"]self.title_graph = parameters["title_graph"]self.title_key = parameters["title_key"]self.index = 0self.base = 0.5self.totalcalls = 0self.info = [{"nome":"noname",

"base1":-1,"chiamate":-1

}]for par in self.sys_name:

self.info.append({"nome":(self.sys_name[self.index]),"base1":self.base,

Page 116: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE C. FILTRI 115

"chiamate":0,"successi":0})

self.base += 1self.index += 1

expected_parameters = {"sys_name":{"type":const().PARAM_LIST,

"doc":"Elenco delle system call","default":["SYS_READ", "SYS_WRITE", "SYS_OPEN",

"SYS_CLOSE", "SYS_IOCTL", "SYS_SELECT","SYS_LLSEEK", "SYS_MMAP2", "SYS_BRK","SYS_RT_SIGACTION"],

"listdef":{"type":const().PARAM_STRING,"doc":"Nome system call"},

"order":1},

"files_path":{"type":const().PARAM_STRING,"doc":"Path dei file generati","default":".","order":2},

"figura_name":{"type":const().PARAM_STRING,"doc":"Nome della figura","default":None,"order":4},

"figura_ext":{"type":const().PARAM_STRING,"doc":"Estensione figura (ps|png)","default":"png","order":5},

"trama_bars":{"type":const().PARAM_INT,"doc":"Trama delle barre (-1|0|1|2|3|4|5|6|7|8|9)","default":-1,"order":6},

"log_y":{"type":const().PARAM_STRING,"doc":"Settare y in scala logaritmica (yes|no)","default":"no","order":7},

"title_graph":{"type":const().PARAM_STRING,"doc":"Titolo del grafico","default":"","order":8},

"title_key":{"type":const().PARAM_STRING,"doc":"Titolo della legenda",

Page 117: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE C. FILTRI 116

"default":"","order":9}

}

Anche in tal caso il costruttore esegue fondamentalmente l’operazione di inizializzazione dellevariabili membro con i parametri che l’utente deve fornire in ingresso al filtro. Similmente aquanto visto in precedenza, molti parametri servono a stabilire la formattazione del graficodi uscita (nome, titolo, trama delle barre, estensione...). Il filtro inoltre riceve in ingressoun parametro di tipo lista dove ogni elemento della lista e una stringa di caratteri. Questoparametro serve a specificare per quali system call il grafico dovra mostrare la relativa barrae viene quindi inizializzato di default con le 10 system call strumentate per gli esperimentidescritti nella sezione 3.5. Sono state aggiunte alcune particolari variabili membro che ser-viranno per tenere traccia delle informazioni che vogliamo rappresentare. Il dizionario infoservira, come vedremo nella prossima sezione, a memorizzare le chiamate relative a ciascunasystem call mentre le varabili index e base sono impiegate per motivi che analizzeremo nellasezione C.2.3.

C.2.2 Il metodo process

Quello che segue e il codice del metodo di processazione relativo al filtro event percent:

def process(self, entity):

nome = entity.getName()

if (nome in self.sys_name):(self.info[self.getIndex(nome)])["chiamate"] += 1self.totalcalls += 1

def getIndex(self, nome):pos = 0while (pos < len(self.info)):

if ((self.info[pos])["nome"] == nome):return pos

pos += 1return 0

L’operazione fondamentale e quella di contare il numero di chiamate di ogni system call. Siparte quindi con l’ispezionare il nome di ogni entita incontrata nel file binario per saperese esso e presente nella lista dei nomi delle system call di interesse. In caso affermativo siincrementa il numero di chiamate relativo e quello assoluto. Il metodo getIndex() servesemplicemente a ricavare l’indice corrispondente nella lista delle system call, indice usato perscorrere la struttura dizionario info.

C.2.3 Il metodo close

Esaminiamo adesso il codice del metodo di chiusura close:

Page 118: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE C. FILTRI 117

def close(self):tmp = 1nomi = ""while (tmp < len(self.info)):

try:dati = open(self.files_path+"/"+((self.info[tmp])["nome"])[4:].lower(),’w’)

except IOError:raise Exception, "Error opening file"

if (tmp != len(self.info)-1):nomi += ("\"%s\" with boxes, "%(((self.info[tmp])["nome"])[4:]).lower())

else:nomi += ("\"%s\" with boxes\n"%(((self.info[tmp])["nome"])[4:]).lower())

dati.write("%f %f\n"%((self.info[tmp])["base1"],float(100*(self.info[tmp])["chiamate"])/float(self.totalcalls),))

tmp += 1dati.flush()dati.close()

try:commands = open(self.files_path +

"/Commands.gnuplot",’w’)except IOError:

raise Exception, "Error opening file"if (self.figura_ext == "ps"):

set = ("postscript landscape 8")out = ("\"%s.ps\""%(self.figura_name))

else:set = ("png")out = ("\"%s.png\""%(self.figura_name))

commands.write("set terminal %s\n"%set)commands.write("set key outside box lw 0.5\n")commands.write("set key title \"%s\"\n"% self.title_key)commands.write("set boxwidth 0.7\n")if (self.log_y == "yes"):

commands.write("set logscale y\n")

commands.write("set title \"%s\"\n"% self.title_graph)commands.write("set output %s\n"%out)trama = str(self.trama_bars)

Page 119: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE C. FILTRI 118

if (trama != "-1"):commands.write("set style fill pattern

%s\n"%str(self.trama_bars))else:

commands.write("set style fill solid\n")commands.write("set grid\n")commands.write("unset xtics\n")commands.write("plot %s"%nomi)commands.flush()commands.close()

A grandi linee esso non e molto diverso da quello analizzato per il filtro precedente mac’e una importante differenza. Il metodo di chiusura di questo filtro non scrive in 2 file ma inalmeno 2. Uno dei file che viene fornito obbligatoriamente in output e quello che contiene icomandi da passare all’applicazione gnuplot per tracciare il grafico a barre. I dati da plottare,a differenza di prima e come gia accennato nella sezione 3.5.2, sono distribuiti in piu file, unoper ogni system call. Cio e necessario perche gnuplot non consente di tracciare un graficoa barre in cui ogni barra faccia riferimento a solo una porzione di un file di dati. Mettendotutti i dati in un unico file essi non sarebbero stati discriminati e le barre avrebbero assuntotutte lo stesso colore. Quindi si e deciso di realizzare un file per ogni system call chiamatocol relativo nome in cui vengono inseriti 2 semplici numeri; il secondo di questi numeri eproprio la percentuale di chiamata mentre il primo serve per distanziare le barre. Quest’ultimainformazione la impostiamo grazie alle varibili base e index inizializzate nel costruttore e dellequali, solo ora che e stato esaminato il metodo close, possiamo comprendere il significato.

C.3 Il filtro event tomysql

L’ultimo filtro costruito e quello gia abbozzato nella sezione 2.5.2. Esso deve semplicementeleggere dal file binario le entita loggate e trasferirle in un database. A tal scopo, e in basealla tipologia degli esperimenti visti nella sezione 3.5 e stato creato il database come mostratonella sezione D.1.

C.3.1 Definizione e costruttore

Cominciamo col riportare la sezione in cui definiamo la classe e viene realizzato il costruttore:

import MySQLdb

class event_tomysql_filter(filter_framework.abstract_filter):"""Memorizza gli eventi in un database mysql.Universita degli studi di Napoli Federico IICristofaro Gozzolino - Paolo Guadagnuolo"""

Page 120: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE C. FILTRI 119

def __init__(self, parameters, _input=None, _output=None):

filter_framework.abstract_filter.__init__(self, _input, _output)

self.username = parameters["username"]self.password = parameters["password"]self.host = parameters["host"]self.db = parameters["db"]self.table = parameters["table"]

self.conn = MySQLdb.connect(host = self.host,user = self.username,passwd = self.password,db = self.db)

self.cur = self.conn.cursor()pass

expected_parameters = {"username":{"type":const().PARAM_STRING, "order":10,

"doc":"Nome Utente database", "default":"root"},"password":{"type":const().PARAM_STRING, "order":20,

"doc":"Password", "default":""},"host":{"type":const().PARAM_STRING, "order":30,

"doc":"Host database", "default":"localhost"},"db":{"type":const().PARAM_STRING, "order":40,

"doc":"Nome Database"},"table":{"type":const().PARAM_STRING, "order":50,

"doc":"Tabella di destinazione", "default":"Event"}}

La prima cosa da fare consiste nell’importare il modulo MySQLdb che ci offre i metodi ne-cessari per stabilire una connessione con un database definito attraverso il DBMS MySQL. Levariabili membro che vengono inizializzate con i parametri di ingresso corrispondenti vengonofornite al metodo connect che stabilisce la connessione. La variabile cur viene mpiegatainvece per memorizzare il cursore con cui ci spostiamo nella tabella interessata nel metodo diprocessazione.

C.3.2 I metodi process e close

Riportiamo infine le implementazioni dei metodi process e close:

def process(self, entity):""" Questa funzione effettua il processing """

Page 121: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE C. FILTRI 120

if(entity.getType() == "EVENT"):extra_data = entity.getExtraData()format = ’i’extra_info = struct.unpack(format, extra_data)if ((extra_info[0] < 0) & (extra_info[0] > -150.0)):

errorcode = extra_info[0]*(-1)else:

errorcode = 0self.cur.execute("INSERT INTO %s VALUES(%d,

\’%s\’, \’%s\’, %d, %d, %f, %f)" %(self.table, entity.getNumber(),entity.getName(), entity.getFamily(),entity.getTime_stamp(), entity.getTag(),extra_info[0], errorcode))

pass

def close(self):self.cur.close()self.conn.close()pass

Il metodo process deve semplicemente inserire nel database le informazioni relative aglieventi incontrati nel file binario. La prima cosa da fare e controllare se l’entita e effettivamenteun evento perche il database e stato realizzato per memorizzare solo entita di questo tipo.Verificato cio si passa all’inserimento dei valori sfruttanto il metodo execute fornito dalmodulo MySQLdb. L’unica informazione che inseriamo in modo alterato e l’extra dato chetra l’altro deve anche subire un’operazione di “unpack” dopo averlo estratto col metodogetExtraData(). Secondo quanto stabilito negli esperimenti descritti nella sezione 3.5 l’extradato contiene il valore di ritorno delle system call, valore che puo essere o negativo o positivo.Ricordiamo pero che alcune system call non tornano semplicemente un intero ma restituisconodegli indirizzi di memoria. Nella sezione 3.5 e stato stabilito che l’extra dato deve essereloggato nel file binario come intero quindi anche un eventuale indirizzo di memoria vieneconvertito in intero e puo diventare un valore negativo (di solito molto alto in valore assoluto).La maggior parte dei codici di uscita delle system call e compresa nell’intervallo tra 1 e 150(in negativo) quindi ecco perche viene eseguito il controllo con il valore -150. Nel caso divalori positivi possiamo essere certi che non c’e codice d’errore e allora convertiamo l’extradato in 0 che tra l’altro e anche il codice d’uscita utilizzato nella maggior parte dei casi perindicare un successo. La conversione viene fatta pero anche per i valori negativi oltre -150che si otterrano quando le system call terminano con successo ma restituiscono un indirizzodi memoria che convertito in intero diventa un valore negativo. Sara quindi necessario, neldatabase, non solo il campo ExtraData ma un campo ulteriore che chiameremo errordocein cui memorizziamo l’informazione “alterata”.

Il metodo di close, diversamente dai casi esaminati nelle sezioni precedenti, non deveprodurre alcun output ma serve semplicemente a chiudere la connessione.

Page 122: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Appendice D

Database e query

In questa sezione forniremo il sorgente SQL per la creazione del database necessario a memo-rizzare le informazioni relative agli eventi loggati dagli esperimenti descritti nella sezione 3.5.Il database viene impiegato dal filtro descritto nella sezione C.3 e viene interrogato attraversola query descritta in questa stessa sezione.

D.1 Creazione database

Il nostro database deve contenere fondamentalmente 3 tabelle, una per ogni esperimento(CPU, IO , MEMORY), in cui inserire tutti i possibili dati degli eventi catturati. Precisamenteavremo un attributo per memorizzare ciascuna delle seguenti informazioni:

1. numero progressivo dell’evento;

2. nome dell’evento;

3. famiglia di cui l’evento fa parte;

4. timestamp relativo dell’istante di generazione;

5. tag;

6. dato extra;

7. codice d’uscita ottenuto dal dato extra come precisato nella sezione C.3.2.

La chiave primaria di tali tabelle puo essere costituita semplicemente dal numero progressivoche e diverso per ogni sessione sperimentale. Poiche siamo interessati a conoscere il significatorelativo di ogni codice d’uscita sara necessario creare una tabella in cui inserire le coppie deltipo (Codice, Nome) e bisognera riempire questa tabella con tutti i possibili elementi. Diseguito viene fornito il sorgente SQL che e possibile importare in mysql per creare il databasecon tutte le tabelle necessarie e riempire la tabella ErrorTable1.

CREATE DATABASE syscall;

1Mostriamo per brevita solo alcuni dei codici inseriti.

121

Page 123: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE D. DATABASE E QUERY 122

use syscall;

CREATE TABLE EventCPU (Num INTEGER,Name VARCHAR(50) NOT NULL,Family VARCHAR(50) NOT NULL,TimeStamp NUMERIC(20) NOT NULL,Tag INTEGER NOT NULL,ExtraData NUMERIC(20),ErrorCode NUMERIC(20),PRIMARY KEY(Num)

);

CREATE TABLE EventIO (Num INTEGER,Name VARCHAR(50) NOT NULL,Family VARCHAR(50) NOT NULL,TimeStamp NUMERIC(20) NOT NULL,Tag INTEGER NOT NULL,ExtraData NUMERIC(20),ErrorCode NUMERIC(20),PRIMARY KEY(Num)

);

CREATE TABLE EventMEM (Num INTEGER,Name VARCHAR(50) NOT NULL,Family VARCHAR(50) NOT NULL,TimeStamp NUMERIC(20) NOT NULL,Tag INTEGER NOT NULL,ExtraData NUMERIC(20),ErrorCode NUMERIC(20),PRIMARY KEY(Num)

);

CREATE TABLE ErrorTable (ErrorName VARCHAR(30) NOT NULL,ErrorCode INTEGER,PRIMARY KEY(ErrorCode)

);

GRANT ALL PRIVILEGES ON syscall.* TO testuser@localhostIDENTIFIED BY ’testpass’;

FLUSH PRIVILEGES;

Page 124: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE D. DATABASE E QUERY 123

INSERT INTO ErrorTable VALUES ("OK", 0);INSERT INTO ErrorTable VALUES ("EPERM", 1);INSERT INTO ErrorTable VALUES ("ENOENT", 2);INSERT INTO ErrorTable VALUES ("ESRCH", 3);INSERT INTO ErrorTable VALUES ("EINTR", 4);INSERT INTO ErrorTable VALUES ("EIO", 5);INSERT INTO ErrorTable VALUES ("ENXIO", 6);INSERT INTO ErrorTable VALUES ("E2BIG", 7);INSERT INTO ErrorTable VALUES ("ENOEXEC", 8);INSERT INTO ErrorTable VALUES ("EBADF", 9);INSERT INTO ErrorTable VALUES ("ECHILD", 10);INSERT INTO ErrorTable VALUES ("EAGAIN", 11);

...

INSERT INTO ErrorTable VALUES ("EKEYREJECTED", 129);INSERT INTO ErrorTable VALUES ("EOWNERDEAD", 130);INSERT INTO ErrorTable VALUES ("ENOTRECOVERABLE", 131);

D.2 Query

Una volta creato il database e riempito con le informazioni relative agli eventi utilizzandoil filtro visto nella sezione C.3 e necessario creare una query per estrarre dal database leinformazioni che ci interessano. La query che segue (relativa al caso CPU bound) ci permettedi ottenere una tabella in cui c’e una riga per ogni coppia (System call, Codice di uscita).Gli ulteriori attributi sono il numero di occorrenze della coppia nonche il numero di chiamatecomplessive della system call; da questi si ottengono i valori che riempiono gli ultimi duecampi ossia la percentuale relativa e assoluta della coppia.

use syscall;

tee error_table_cpu1.txt;

SELECT ErrorTable.ErrorName, EventCPU.Name,COUNT(ErrorTable.ErrorCode) AS Occorrenze,T.Totale, 100*COUNT(ErrorTable.ErrorCode)/T.Totale AS PercRel,(100*COUNT(ErrorTable.ErrorCode)/(SELECT COUNT(*) FROM EventCPU))AS PercAss

FROM EventCPU, ErrorTable,(SELECT COUNT(*) AS Totale,Name FROM EventCPU GROUP BY EventCPU.Name) AS T

WHERE ErrorTable.ErrorCode = EventCPU.ErrorCodeAND T.Name = EventCPU.Name

GROUP BY EventCPU.Name, ErrorTable.ErrorCodeORDER BY EventCPU.Name;

Page 125: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

APPENDICE D. DATABASE E QUERY 124

notee;

Importando questo script in mysql otterremo la tabella desiderata direttamente in un filedi testo in uscita. Ovviamente lo stesso script va costruito per il caso IO e Memory bound,mdificando banalmente tutti i suffissi cpu/CPU.

Page 126: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Appendice E

Codici di errore

La tabella seguente riporta i codici d’errore maggiormente accorsi negli esperimenti descrittiin precedenza.

Nome Errore DescrizioneEACCESS Permesso negatoEADDRNOTAVAIL Indirizzo non disponibileEAGAIN Risorsa temporaneamente occupataEBADF Descrittore di file erratoECHILD Nessun processo figlioEINTR Chiamata di funzione interrottaEINVAL Argomento non validoENOENT File o directory non esistenteENOEXEC Formato della exec erratoENOTSOCK L’entita non e una socketENOTTY Inappropriata operazione di controllo IOENXIO Dispositivo o indirizzo non esistenteEPERM Operazione non permessaESPIPE Ricerca non valida

Tabella E.1: Codici d’errore ottenuti nei risultati sperimentali.

125

Page 127: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

Bibliografia

[1] Paolo Guadagnuolo: Studio ed implementazione di meccanismi di probing del kernel 2.6di Linux, 2006

[2] Herbert Schildt: C/C++ Programmer’s Reference, 3rd edition, McGraw-Hill, 2003

[3] Robert Love: Linux Kernel Development, 2nd edition, Novell, 2005

[4] Daniel P. Bovet, Marco Cesati: Understanding the Linux Kernel, 3rd Edition, O’Reilly,2006

[5] Peter Jay Salzman, Michael Burian, Ori Pomerantz: The Linux Kernel ModuleProgramming Guide, Peter Jay Salzman, 2001

[6] Jonathan Corbet, Alessandro Rubini, Greg Kroah-Hartman: Linux Device Drivers, 3rdEdition, O’Reilly, 2005

[7] Thomas Williams, Colin Kelley: Gnuplot - An Interactive Plotting Program, Version 4.0,2004

[8] John W. Eaton: GNU Octave, 3rd Edition, www.octave.org, 1997

[9] Guido van Rossum: Python Tutorial, Release 2.4.2, Python Software Foundation, 2005

[10] Guido van Rossum: Python Library Reference, Release 2.4.2, Python SoftwareFoundation, 2005

[11] Guido van Rossum: Python Reference Manual, Release 2.4.2, Python SoftwareFoundation, 2005

[12] John Finlay: PyGTK 2.0 Tutorial, http://www.pygtk.org/, 2005

[13] Leslie Lamport: LATEX, A Document Preparation System, 2nd Edition, Addison-WesleyPublishing Company, 1994

[14] Michel Goossens, Sebastian Rahtz, Frank Mittelbach: The LATEXGraphics Companion,Addison-Wesley Publishing Company, 1997

[15] Tobias Oetiker, Hubert Partl, Irene Hyna, Elisabeth Schlegl: The Not So ShortIntroduction to LATEX2ε, ftp://ftp.unina.it/pub/TeX/info/italian, 2000

[16] Tejasvi Aswathanarayana, Douglas Niehaus, Venkita Subramonian, ChristopherGill: Design and Performance of Configurable Endsystem Scheduling Mechanisms,http://...

126

Page 128: Monitoring delle system call del sistema operativo Linux ... · La letteratura inquadra il sistema operativo Linux tra i sistemi monolitici ossia quelli costituiti da un unico grande

BIBLIOGRAFIA 127

[17] Datastreams End-To-End Tutorial1,KUSP/tutorials/end-to-end/end-to-end.pdf

[18] Deepti Mokkapati: Instrumenting kernel code with DSKI,KUSP/tutorials/dski/how to instrument dski.pdf

[19] Tejasvi Aswathanarayana: Instrumenting code with DSUI,KUSP/tutorials/dsui/how to instrument dsui.pdf

[20] Ashwin Kumar Chimata: Logging and Analyzing Kernel Data using Datastream GUIs,KUSP/tutorials/first expr/first exp doc.pdf

[21] Andrew Boie: Filter Configuration Parser,KUSP/postprocess/filter config parser/filter config parser.pdf

[22] Noah Watkins: Postprocessing Documentation,KUSP/postprocess/filtering framework/postprocess.pdf

[23] Noah Watkins: Namespace Configuration GUI,KUSP/gui/namespaces/nsconfig.pdf

[24] Noah Watkins: Experiment Configuration GUI,KUSP/gui/experiments/xpconfig.pdf

[25] Noah Watkins, Andrew Boie: Filter Configuration GUI,KUSP/gui/pipelines/filter config gui.pdf

[26] Noah Watkins: Visualization GUI,KUSP/gui/visualizer/ds visualizer.pdf

“”

1D’ora in poi KUSP=(Path Kusp doc)/datastreams/