ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di...

127
UNIVERSITÀ DEGLI STUDI DI NAPOLI FEDERICO II FACOLTÀ DI INGEGNERIA CORSO DI LAUREA SPECIALISTICA IN INGEGNERIA INFORMATICA (CLASSE DELLE LAUREE SPECIALISTICHE IN INGEGNERIA INFORMATICA N.35/S) DIPARTIMENTO DI INFORMATICA E SISTEMISTICA ELABORATO DI LAUREA Analisi sperimentale di software aging nel kernel Linux RELATORE CANDIDATO Ch.mo Prof. Stefano Russo Berniero Volzone Matr.: 885/288 CORRELATORI Ing. Roberto Natella Ing. Roberto Pietrantuono ANNO ACCADEMICO 2008/2009

Transcript of ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di...

Page 1: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

UNIVERSITÀ DEGLI STUDI DI NAPOLI FEDERICO II

FACOLTÀ DI INGEGNERIA

CORSO DI LAUREA SPECIALISTICA IN INGEGNERIA INFORMATICA

(CLASSE DELLE LAUREE SPECIALISTICHE IN INGEGNERIA INFORMATICA N.35/S)

DIPARTIMENTO DI INFORMATICA E SISTEMISTICA

ELABORATO DI LAUREA

Analisi sperimentale di software aging nel kernel Linux

RELATORE CANDIDATO Ch.mo Prof. Stefano Russo Berniero Volzone

Matr.: 885/288 CORRELATORI Ing. Roberto Natella Ing. Roberto Pietrantuono

ANNO ACCADEMICO 2008/2009

Page 2: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Facoltà di Ingegneria Corso di Studi in Ingegneria Informatica Tesi di laurea specialistica

Analisi sperimentale di

software aging nel kernel Linux Anno Accademico 2008/09 Relatore Ch.mo Prof. Stefano Russo Correlatori Ing. Roberto Natella Ing. Roberto Pietrantuono Candidato Berniero Volzone matr.: 885/288

Page 3: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

I

Indice

Introduzione 1

Capitolo 1 Dependable Computing e software aging 5 1.1 Dependability dei sistemi informatici 6

1.2 Fallimenti, errori e guasti 10

1.2.1 Fallimenti 12

1.2.2 Errori 16

1.2.3 Guasti 17

1.2.3.1 Guasti software 20

1.3 Metodi per migliorare la dependability del software 23

1.4 Software aging 26

1.5 Metodi per l’analisi dell’aging 28

1.5.1 Analytical modeling 29

1.5.2 Measurement-Based Approach 33

1.6 Software rejuvenation 36

Capitolo 2 Software aging nei sistemi operativi 39 2.1 Sistemi operativi e dependability 40

2.2 Studi correlati 43

Capitolo 3 Instrumentazione del sistema operativo Linux 50 3.1 Struttura del sistema operativo Linux 50

Page 4: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

II

3.1.1 Sottosistemi del kernel 57

3.1.1.1 Process management 58

3.1.1.2 Memory management 59

3.1.1.3 File system e device control 60

3.1.1.4 Networking 62

3.1.2 Process file system 63

3.2 Tracepoint nel kernel Linux 64

3.3 Individuazione delle informazioni di interesse 67

3.4 Instrumentazione dei tracepoint e definizione del tracer 70

3.4.1 Rappresentazione dei dati relativi al tempo di latenza 74

3.5 Scrittura delle informazioni di sistema su file: myTracer-rep 78

Capitolo 4. Procedura sperimentale 81 4.1 Design of Experiments (DoE) 82

4.2 Software aging nel kernel Linux: procedura sperimentale 87

4.3 Progettazione degli esperimenti 89

4.3.1 Analisi di software aging 91

4.3.1.1 Raccolta dei dati e preprocessing 92

4.3.1.2 Test di Mann-Kendall e metodo di Sen 94

4.3.1.3 Principal component analysis 97

Capitolo 5. Sperimentazione ed analisi dei risultati 100 5.1 Esecuzione del test 101

5.1.1 Individuazione dei trend di aging 103

5.1.2 Principal component analysis 108

5.1.3 Valutazione dei risultati 110

Conclusioni e sviluppi futuri 115

Bibliografia 118

Page 5: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

III

Indice delle figure

Figura 1.1: diagramma di stato failure-repair. 6

Figura 1.2: diagramma di stato failure-repair con politica di tolleranza ai guasti. 9

Figura 1.3: relazione fra MTTF, MTBF ed MTTR. 10

Figura 1.4: relazione fra fallimenti, errori e guasti. 11

Figura 1.5: tassonomia di fallimenti. 15

Figura 1.6: classi di fault elementari. 17

Figura 1.7: classi di fault combinate. 18

Figura 1.8: metodi di fault tolerance. 24

Figura 1.9: aging-related bugs. 27

Figura 1.10: modello semi-Markoviano. 30

Figura 1.11: modello semi-Markoviano modificato. 31

Figura 1.12: confronto tra i modelli semi-Markoviano e semi-Markoviano modificato. 32

Figura 1.13: modello MRSPN di software rejuvenation. 33

Figura 1.14: esempio di approccio measurement-based. 35

Figura 1.15: approcci di software rejuvenation. 38

Figura 2.1: albero MIB per il modulo PFM del tool di monitoring SNMP. 44

Figura 2.2: monitoring delle informazioni UNIX tramite SNMP. 45

Figura 3.1: architettura fondamentale del SO Linux. 52

Figura 3.2: esempio di system call nel SO Linux. 53

Figura 3.3: transizione tra user e kernel mode per l’esecuzione di due processi. 55

Figura 3.4: accesso alla memoria nella commutazione tra user e kernel mode. 56

Page 6: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

IV

Figura 3.5: sottosistemi del kernel Linux. 57

Figura 3.6 strumento di monitoring. 72

Figura 3.7 istogramma della latenza della system call open catturata in un unico

evento. 75

Figura 3.8 istogramma della latenza della system call open catturata in eventi

successivi. 76

Figura 3.9a formattazione dei dati contenuti nel file mem.txt. 79

Figura 3.9b formattazione dei dati contenuti nel file proc.txt. 79

Figura 3.9c formattazione dei dati contenuti nel file disk.txt. 80

Figura 3.9d formattazione dei dati contenuti nel file net.txt. 80

Figura 3.9e formattazione dei dati contenuti nel file filesys.txt. 80

Figura 4.1 modello procedurale per lo studio del software aging. 88

Figura 4.2 processo di elaborazione delle informazioni di sistema. 91

Figura 5.1 procedura sperimentale. 101

Figura 5.2 procedura di analisi dei dati. 102

Figura 5.3: variazione della memoria fisica libera disponibile. 104

Figura 5.4: trend relativo all’indicatore di memory depletion. 105

Figura 5.5: trend relativo all’indicatore di throughput loss del sottosistema

memory management. 106

Figura 5.6: trend relativo all’indicatore di time loss del sottosistema

memory management. 106

Figura 5.7: composizione della prima e della terza PC relative al

sottosistema file system I/O. 111

Figura 5.8: composizione della prima e della seconda PC relative al

sottosistema disk I/O driver. 111

Figura 5.9: composizione della prima e della seconda PC relative al sottosistema

memory management. 112

Figura 5.10: composizione della prima PC relativa al sottosistema process

management. 112

Page 7: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

V

Indice delle tabelle

Tabella 1.1: metriche per la valutazione della dependability. 10

Tabella 3.1: informazioni di tracing per i sottosistemi di memory management e

process management. 69

Tabella 3.2: informazioni di tracing per i sottosistemi di network I/O e file system I/O. 69

Tabella 3.3: informazioni di tracing per il sottosistema disk I/O driver. 70

Tabella 5.1: sintesi dei risultati ottenuti. 107

Tabella 5.2: coefficienti delle componenti principali relative al sottosistema

disk I/O driver. 109

Tabella 5.3: coefficienti delle componenti principali relative al sottosistema

process management. 109

Tabella 5.4: coefficienti delle componenti principali relative al sottosistema

file system I/O. 110

Tabella 5.5: coefficienti delle componenti principali relative al sottosistema

memory management. 110

Tabella 5.6: parametri di workload più significativi per ogni trend

e per ogni sottosistema. 113

Page 8: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

1

Introduzione

Il presente lavoro di tesi è frutto di un’attività di ricerca e sperimentazione, svoltasi

presso il laboratorio CINI (Consorzio Interuniversitario Nazionale per l’Informatica) della

Federico II, con lo scopo di analizzare il fenomeno di aging nel sistema operativo Linux.

Il software aging può essere definito come il graduale accumulo di potenziali condizioni

di fault durante l’esecuzione di un programma, che conduce ad una degradazione nelle

prestazioni del sistema ed eventualmente al crash [1]. Per tale ragione, lo studio

approfondito di soluzioni che assicurino elevata affidabilità non può prescindere

dall’analisi dell’invecchiamento software, che è stata così incoraggiata dal diffondersi delle

applicazioni mission/business critical.

Gli studi sul software aging e sulle correlate tecniche di rejuvenation sono relativamente

recenti. Essi risalgono, infatti, alla metà degli anni ’90 e si concentrano, per la maggior

parte, su modelli analitici e statistici atti alla descrizione del fenomeno. Negli ultimi anni,

tuttavia, si sono diffuse una miriade di applicazioni aventi esigenze sempre più critiche in

termini di affidabilità. Mentre le tecniche di fault tolerance hardware appaiono ormai ben

consolidate, i fallimenti software continuano a configurarsi come un problema solo

parzialmente risolto, che costituisce una minaccia per le applicazioni con requisiti di

elevata dependability. Nonostante l’evoluzione delle tecniche di ingegneria del software,

l’eliminazione di tutti i bug durante le fasi di progettazione e di testing resta un concetto

ideale. Basti pensare che taluni fault, per loro stessa natura, non emergono nell’ambiente di

Page 9: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

2

test ma solo in quello di reale funzionamento (ad esempio, perché sono dovuti

all’integrazione con sistemi di notevole dimensione e complessità). Bisogna poi tener

presente che le cause più comuni dell’aging (memory leaking, memory bloating, lock su

file non rilasciati, frammentazione dei dischi, accumulo di errori di round-off, ecc.) non

sono facilmente individuabili con il testing poiché l’applicazione ne esibisce le

conseguenze solo dopo un lungo periodo di funzionamento.

Tali caratteristiche peculiari conferiscono al problema dell’aging una particolare difficoltà,

la quale risulta amplificata nel caso si intenda studiare l’invecchiamento di un sistema

operativo (SO). Infatti, quest’ultimo è un’applicazione di notevole complessità che offre

gli strumenti per la corretta gestione di tutte le risorse di un calcolatore [2]. Tale

definizione implica diversi problemi nello studio dell’aging. In primo luogo, poiché il SO

supervisiona l’utilizzo di tutte le risorse del sistema di calcolo (processi, memoria centrale

e di massa, dispositivi di I/O, ecc.), risulta notevolmente difficile definire un modello

esaustivo, analitico o statistico, che consideri le cause e gli effetti dell’aging nei diversi

sottosistemi. In secondo luogo, l’utilizzo di strumenti di benchmark per la valutazione di

indicatori di aging può influenzare la misura stessa rendendo falsata l’analisi. Ciò è

inevitabile per due ragioni. Innanzitutto, poiché lo strumento di benchmark è esso stesso un

processo che richiede risorse al sistema operativo, un’analisi dell’aging che abbia

l’obiettivo di misurare l’esaurimento delle risorse computazionali dovrebbe effettuare

anche una stima precisa di quelle che lo strumento di benchmark richiede per funzionare.

Inoltre, essendo lo strumento stesso un’applicazione software, non è escluso a priori che

esso possa causare involontariamente una porzione dell’invecchiamento che si ha lo scopo

di misurare.

Questi concetti sono approfonditi nel corso della tesi, che si propone di analizzare il SO

Linux al fine di determinare se esso risulti affetto da aging. Vengono tracciate le linee

guida per l’applicazione di una procedura utile:

- alla rilevazione dell’aging;

- all’individuazione delle porzioni del kernel che risultino maggiormente legate al

Page 10: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

3

fenomeno;

- alla stima del Time To Exhaustion (TTE) delle risorse.

Lo scopo di siffatta analisi consiste, in primo luogo, nel fornire agli sviluppatori del SO un

insieme di valutazioni utili a ridurre i tempi ed i costi per le operazioni di debugging,

mirate al miglioramento generale delle future versioni del kernel. Inoltre, la proposta di

una procedura finalizzata alla stima del TTE delle risorse è rivolta principalmente agli

amministratori dei sistemi Linux long running, i quali possono determinare il periodo di

tempo tra opportuni interventi di ripristino, in considerazione delle particolari condizioni

medie di carico del sistema che gestiscono.

Nello specifico, la tesi si propone di illustrare lo sviluppo ed il funzionamento di uno

strumento in grado di monitorare lo “stato di salute” del SO Linux, attraverso

l’introduzione di sonde per il tracciamento delle informazioni di sistema. Nel lavoro svolto,

tale strumento viene adoperato per lo studio del software aging ma ciò non preclude un suo

utilizzo per fini diversi, che coinvolgano il monitoraggio dello stato delle risorse di

sistema.

La struttura della tesi può essere schematizzata come segue. Il primo capitolo introduce

le definizioni generali inerenti all’affidabilità dei sistemi informatici, per poi focalizzare

l’attenzione sull’aging. Dopo averne descritte le cause, si passano in rassegna le varie

tecniche proposte in letteratura per l’analisi del fenomeno e per la sua prevenzione

(rejuvenation).

Nel secondo capitolo sono invece esposte le problematiche riguardanti lo studio

dell’invecchiamento dei sistemi operativi. L’analisi qui condotta parte della descrizione

delle vulnerabilità dei SO in generale e presenta alcune metodologie proposte in letteratura

per lo studio del software aging in ambienti UNIX e Linux. Lo scopo principale consiste

nel comprendere lo stato dell’arte riguardo agli studi condotti sull’invecchiamento dei SO,

in modo da costituire un background di conoscenza da cui partire nella proposta di una

nuova procedura.

Il terzo capitolo descrive la struttura di Linux di cui viene presentata l’architettura e la

Page 11: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

4

suddivisione in sottosistemi. Tale analisi è mirata alla comprensione delle ragioni che

inducono il kernel ad invecchiare, nonché all’identificazione delle porzioni più vulnerabili

e delle informazioni che possono essere monitorate per controllare lo “stato di salute” del

SO. Viene quindi descritto un meccanismo di tracciamento che consenta di reperire i dati

sensibili riguardo alle singole componenti.

Il quarto ed il quinto capitolo presentano, rispettivamente, la procedura sperimentale

adottata per l’analisi dell’aging nel kernel Linux ed i risultati delle misurazioni effettuate,

relativamente ad un sottoinsieme di indicatori precedentemente individuati. A tale scopo,

viene descritta una serie di strumenti statistici utili all’analisi dei dati che, opportunamente

adattati, consentono di ottenere i risultati illustrati, attraverso grafici e tabelle, nell’ultimo

capitolo.

Page 12: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

5

Capitolo 1 Dependable Computing e software aging

Negli ultimi quarant’anni, grazie alla diffusione capillare dell’ICT nei più svariati campi

d’applicazione, le aspettative nei confronti dei sistemi informatici, e particolarmente del

software, sono mutate radicalmente. Internet, il web e la multimedialità appartengono,

ormai, alle abitudini quotidiane di ciascuno e, parallelamente, i sistemi informatici sono

utilizzati in scenari critici sia dal punto di vista economico (business critical) che in termini

di affidabilità e sicurezza (mission critical). Si pensi, ad esempio, ad applicazioni quali il

controllo del traffico ferroviario ed aereo, il controllo remoto di veicoli senza conducente,

le missioni aerospaziali, i software di monitoraggio della apparecchiature mediche, nonché

alle applicazioni bancarie e di e-commerce.

In siffatti scenari viene spontaneo chiedersi se ci si può fidare dei computer, quali siano i

rischi che si corrono e come sia possibile prevenirli o porvi rimedio. L’affidabilità di un

sistema informatico, come si vedrà in seguito, è definita come un macroattributo, cioè un

insieme di indicatori di qualità. Per tale ragione, moltissime sono le cause capaci di

degradare la dependability di un servizio, fino a farla scendere al di sotto di livelli ritenuti

accettabili.

Questo capitolo si propone, allora, di introdurre i concetti generali inerenti

all’affidabilità dei sistemi informatici, per poi focalizzare l’attenzione su un particolare

fenomeno in grado di inficiare la dependability del software: l’aging. Dopo la definizione

dell’invecchiamento del software, ne varranno chiarite le cause e gli effetti e si farà una

Page 13: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

6

breve panoramica sui vari approcci proposti in letteratura per l’analisi e la soluzione del

fenomeno.

1.1 Dependability dei sistemi informatici

Introduciamo di seguito la terminologia ed i concetti di base riguardanti l’affidabilità dei

sistemi informatici [3].

Prima di spiegare cosa si intende per dependability, è necessario fornire alcune

definizioni fondamentali. Un sistema è una qualsiasi entità in grado di interagire con altre

entità (sistemi o utenti umani). Per servizio si intende il comportamento del sistema

percepito dall’utente attraverso una cosiddetta interfaccia che rappresenta, appunto, il

confine fra sistema ed utente.

Un servizio si dice corretto se è conforme alle specifiche, mentre si parla di failure quando

il servizio fornito dal sistema non è corretto. Più precisamente un fallimento è, come

esemplifica la figura 1, una transizione dall’erogazione di un servizio corretto a quella di

un servizio scorretto; la transizione opposta viene detta comunemente restoration (o

riparazione).

Figura 1.1: diagramma di stato failure-repair.

Poiché un servizio è una sequenza di stati esterni del sistema, un service failure consiste

nella deviazione di uno o più stati esterni dalle specifiche. La singola deviazione è indicata

con il termine errore mentre la causa di un errore si dice fault (ossia guasto). È possibile

che un fault generi più di un errore all’interno del sistema: in tal caso si parla di multiple

Page 14: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

7

related error. Un errore è, quindi, quella parte dello stato del sistema che può indurre lo

stesso ad un fallimento. Se il sistema è composto da più componenti, un errore può

condurre ad un fallimento in uno di questi che a sua volta, poiché i componenti

interagiscono, può introdurre uno o più fault nelle altre parti. È importante notare che,

comunque, non tutti gli errori raggiungono lo stato esterno del sistema scatenando un

fallimento, cioè non tutti gli errori esibiscono conseguenze percepibili dall’utente.

A questo punto è possibile fornire due definizioni alternative di dependability:

- la capacità del sistema di erogare un servizio che può essere ritenuto legittimamente

fidato;

- la capacità del sistema di evitare che un servizio fallisca più frequentemente e con

conseguenze più severe rispetto ad un certo grado di accettabilità.

Le due definizioni mettono in evidenza che, per decidere se un servizio può essere ritenuto

affidabile, è sempre necessario fissare prima un concetto di fiducia oppure di accettabilità.

La nozione di dependability è associata a quella di dependence: la dipendenza di un

sistema A da un sistema B rappresenta il punto fin cui la dependability di A è (o potrebbe

essere) influenzata da quella di B. Si può così definire la fiducia come il grado di

dipendenza ammessa.

Più nello specifico, si ritiene che la dependability sia un macroattributo, ossia un

insieme dei seguenti indicatori di qualità:

- availability;

- reliability;

- safety;

- performability;

- maintainability.

L’availability è la disponibilità di un certo servizio, ossia la probabilità che non ci sia un

fallimento al tempo t. In altre parole, si dice che un sistema è available in un certo istante

se in quell’istante è in grado di fornire un servizio corretto. Poiché l’availability è

interpretata come un valore medio, ossia come la probabilità che in un dato istante il

Page 15: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

8

sistema sia disponibile o meno, un sistema indisponibile, ad esempio, 2 secondi al minuto

ed uno indisponibile per un intero giorno ogni anno hanno lo stesso valore di availability.

La reliability è la misura della durata dell’intervallo di tempo durante il quale il sistema

fornisce, in maniera continuativa, un servizio corretto. In termini probabilistici, si può

definire la reliability nell’istante t come la probabilità che non ci sia un fallimento

nell’intervallo di tempo (0, t).

La safety è l’assenza di condizioni di funzionamento del sistema che possano provocare

danni a persone o cose. Essa è cioè la probabilità che non occorra un fallimento cosiddetto

catastrofico nell’intervallo di tempo (0, t). Per dichiarare un failure catastrofico si ricorre

ad una valutazione soggettiva dei rischi.

La performability è una metrica introdotta per valutare le prestazioni del sistema anche in

caso di guasti. In pratica, le definizioni di availability e reliability presuppongono che lo

stato del sistema sia binario, cioè che possa essere erogato al tempo t un servizio corretto

(stato up) o scorretto (stato down). Tale assunzione è vera per quei sistemi che non

implementano politiche di tolleranza ai guasti ma, nei casi fault tolerant, possono essere

definiti più stati. In pratica, quando la specifica funzionale del sistema descrive un insieme

di funzioni da erogare, un fallimento in uno o più servizi può lasciare il sistema in uno

stato degenere (ad esempio servizio lento, servizio limitato, servizio di emergenza, ecc.) in

cui viene fornito all’utente solo un insieme ristretto di funzionalità (figura 1.2): in tal caso

si parla di fallimento parziale. La performability è allora una metrica necessaria a misurare

la degradazione delle performance in un sistema che ammette stati di funzionamento

intermedi fra quello di up e down.

La maintainability, infine, è la capacità di un sistema di essere facilmente sottoposto a

modifiche e riparazioni. In termini probabilistici, essa è definita come la probabilità di

effettuare una riparazione con successo in un certo tempo. La maintainability misura,

quindi, il grado di velocità con cui il sistema può essere ripristinato dopo l’occorrenza di

un fallimento.

Page 16: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

9

Figura 1.2: diagramma di stato failure-repair con politica di tolleranza ai guasti.

Per una stima quantitativa del grado di dependability di un sistema vengono utilizzate,

nella pratica, metriche di tipo statistico. Alcune di esse sono abbastanza generali per essere

applicate a qualsiasi servizio e sono basate sui parametri mostrati in tabella 1.1. Queste

misure sono utili a valutare gli attributi di dependability descritti precedentemente. Ad

esempio, si può definire l’availability come:

MTBFMTTF

MTTRMTTFMTTFA =+

= .

A titolo di esempio, si consideri un sistema che fallisce, in media, una volta all’ora ma si

ripristina automaticamente in 10 ms. In base alla definizione precedente, il sistema in

questione risulta notevolmente available poiché si ha:

Page 17: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

10

99999722,001,03600

3600

01,010

36001=

+=⇒

⎪⎭

⎪⎬⎫

==

==A

smsMTTR

shMTTF

PARAMETRO ACRONIMO DESCRIZIONE

Mean Time To Crash MTTC tempo medio di occorrenza di un crash

Mean Time Between Crashes MTBC tempo medio tra due crash

successivi

Mean Time To Failure MTTF tempo medio di occorrenza di un failure

Mean Time Between Failure MTBF tempo medio tra due failure

successivi Mean Number of

Instruction to Restart MNIR numero medio di istruzioni per il ripristino del sistema

Mean Time To Repair MTTR tempo medio necessario per riparare il sistema

Mean Down Time MDT tempo medio durante il quale il sistema non è funzionante

Mean Time Between Errors MRBE tempo medio fra due errori successivi

Tabella 1.1: metriche per la valutazione della dependability.

La figura 1.3 esemplifica la relazione fra le metriche MTTF, MTBF ed MTTR.

Figura 1.3: relazione fra MTTF, MTBF ed MTTR.

1.2 Fallimenti, errori e guasti

Come accennato precedentemente, un failure può essere definito come l’evento in

corrispondenza del quale il sistema cessa di fornire un servizio corretto. Un servizio può in

generale non essere corretto se non è conforme alle specifiche funzionali oppure se la sua

Page 18: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

11

specifica, in fase di analisi dei requisiti, non ha descritto adeguatamente le funzionalità del

sistema. Un errore è la parte dello stato di un sistema che può indurre lo stesso al

fallimento (unproper service). Se l’errore è opportunamente rilevato esso si dice detected

error, viceversa se l’errore esiste ma non è rilevato si parla di latent error. La causa di un

errore è un fault (guasto), che può derivare dall’avaria di un componente hardware, da

fenomeni di interferenza o da errori di progettazione. La figura 1.4 schematizza le relazioni

fra failure, error e fault. In particolare, l’attivazione di un guasto provoca la transizione del

sistema da uno stato di corretto funzionamento (correct behavior) ad uno stato improprio

(errore). Un errore può poi degenerare in un fallimento mediante propagazione

all’interfaccia utente che rende visibile l’anomalia attraverso la scorrettezza del servizio

fornito. La rilevazione di un errore e le opportune operazioni di ripristino possono in

seguito riportare il sistema ad operare in maniera corretta.

Figura 1.4: relazione fra fallimenti, errori e guasti.

Un sistema può portarsi in uno stato incoerente in ogni fase del suo ciclo di vita a causa

di guasti hardware, errori in fase di progettazione, errati interventi di manutenzione ecc.. Il

ciclo di vita di un sistema può essere suddiviso in due macrofasi: lo sviluppo e l’uso.

La fase di sviluppo include tutte quelle attività necessarie affinché il concetto iniziale del

committente si concretizzi in un sistema finale, in grado di fornire il servizio richiesto

nell’ambiente reale di utilizzo. A partire dallo stato embrionale, il sistema interagisce con

Page 19: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

12

l’ambiente di sviluppo ed è soggetto ai cosiddetti fault di sviluppo che possono essere

causati da uno degli elementi che costituisce l’ambiente:

- il mondo fisico, con i suoi fenomeni naturali;

- gli sviluppatori umani;

- i tool di sviluppo, produzione e testing.

La fase di utilizzo ha inizio quando il sistema viene accettato dall’utente e comincia a

fornire i suoi servizi. L’uso consiste, in particolare, in periodi alternati di corretto

funzionamento, di deviazione dalle specifiche e di spegnimento volontario finalizzato ad

attività di manutenzione. Durante la fase d’utilizzo il sistema interagisce con l’ambiente

d’uso, il quale può introdurre guasti attraverso una delle sue entità:

- il mondo fisico, con i suoi fenomeni naturali;

- gli amministratori, cioè le entità (persone o altri sistemi) che hanno l’autorizzazione

ad usare, gestire, manutenere e riparare il sistema;

- gli utenti, ossia le entità (persone o altri sistemi) che fruiscono dei servizi del sistema

attraverso le sue interfacce;

- i provider (persone o altri sistemi) che forniscono a loro volta servizi al sistema;

- l’infrastruttura, costituita da entità in grado di procurare servizi specializzati come

fonti di informazione (ad esempio, clock, GPS, ecc.), link di comunicazione, sorgenti

di potenza, sistemi di raffreddamento, ecc.;

- gli intrusi, ossia entità (persone o altri sistemi) che cercano di alterare i servizi forniti

dal sistema, di renderlo indisponibile o di degradarne le prestazioni.

Nei tre paragrafi seguenti si espongono alcune tassonomie di failure, error e fault

dettagliate in [3].

1.2.1 Fallimenti

L’occorrenza di un fallimento va definita in relazione alla funzione del sistema

desiderata dall’utente finale e non rispetto alla specifica funzionale fissata in fase di analisi.

Page 20: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

13

Ciò significa che un servizio conforme alle specifiche può essere inaccettabile per un

utilizzatore, ad esempio a causa di omissioni, cattive interpretazioni, assunzioni

indesiderate o inconsistenze. In tal caso, il fatto che un evento è indesiderato può essere

rilevato solo allorché l’evento stesso si presenta, scatenando una serie di conseguenze più o

meno severe. Questa natura soggettiva dei fallimenti fa sì che, generalmente, un sistema

possa fallire in modalità differenti, denominate failure mode, le quali implicano la non

correttezza del servizio secondo quattro diversi punti di vista: dominio, rilevabilità,

percezione e rilevanza del fallimento.

Dal punto di vista del dominio è possibile distinguere:

- timing failure o fallimenti nel tempo, che causano la non conformità di un servizio

alle specifiche in termini di tempo (cioè il verificarsi di un evento nel momento

sbagliato). Fallimenti di questo tipo possono essere poi specializzati in early timing

failure, se il servizio è fornito in anticipo, e late timing failure, se in ritardo;

- content failure o fallimenti nel valore, a seguito dei quali il contenuto informativo del

servizio perviene all’interfaccia in maniera non conforme alle specifiche.

Qualora un sistema fallisca sia nel tempo che nel valore, esso può fornire non

correttamente il servizio in diverse modalità, tra cui:

- halted, quando il sistema permane in uno stato bloccato senza che l’output riesca a

pervenire all’interfaccia. Un particolare fallimento di questo tipo è l’omission failure,

che si ha quando il servizio assume un valore nullo ed un ritardo infinito. Un

omission failure permanente prende il nome di crash;

- erratic, quando il servizio fornisce all’interfaccia informazioni incoerenti.

Dal punto di vista della rilevabilità del fallimento si distinguono:

- signaled failure o fallimenti rilevati, segnalati a livello utente da un opportuno

messaggio di errore;

- unsignaled failure o fallimenti non rilevati, cioè non segnalati a livello utente.

I meccanismi stessi di rilevazione possono fallire in due modi:

Page 21: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

14

- segnalando la perdita di una funzionalità quando in realtà non c’è stato alcun

fallimento (si parla in tal caso di falso allarme);

- omettendo la segnalazione di una mancanza di funzionalità (si ha, cioè, un fallimento

non rilevato).

In taluni sistemi i fallimenti di specifiche funzionalità implicano la riduzione del servizio

ed il sistema stesso è in grado di segnalare agli utenti che la modalità di funzionamento

risulta degradata. Questo approccio può essere utile per ridurre l’emergenza di alcune

situazioni o per consentire, ad esempio, uno spegnimento sicuro degli apparati con finalità

di manutenzione.

Dal punto di vista della percezione del fallimento si distinguono:

- consistent failure o fallimenti consistenti, che inducono tutti gli utenti del sistema ad

avere la stessa percezione del failure;

- unconsistent failure o fallimenti inconsistenti, che possono essere percepiti in

maniera diversa dagli utenti del sistema. Fallimenti di questo tipo sono generalmente

indicati come bizantini.

La stima quantitativa delle conseguenze provocate dal failure sull’ambiente induce alla

definizione di severità del fallimento, legata al costo necessario per il ripristino. I failure

mode possono quindi essere ordinati secondo livelli di severità cui sono associati, di solito,

valori di probabilità di occorrenza massimi accettabili. Il numero e la definizione dei livelli

di severità, così come le probabilità associate, dipendono dall’applicazione considerata

nonché dagli attributi di dependability che risultano più appropriati alla caratterizzazione

del sistema in questione. Ad un alto livello di astrazione, si possono definire due valori

limite di severità, considerando la relazione fra i benefici erogati dal sistema in assenza di

fallimenti e le conseguenze di un singolo failure:

- catastrophic failure o fallimenti catastrofici, che provocano conseguenze al sistema

più gravi di molti ordini di grandezza rispetto al beneficio prodotto dal servizio

fornito in assenza di fallimento;

Page 22: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

15

- minor failure o fallimenti benigni, che ingenerano conseguenze dello stesso ordine di

grandezza (valutato in termini di costo) del beneficio prodotto dal servizio fornito in

assenza di fallimento.

Una schematizzazione di quanto appena esposto è riportata in figura 1.5.

Figura 1.5: tassonomia di fallimenti.

I sistemi che sono progettati ed implementati in modo da fallire solamente in specifiche

modalità ed entro certi limiti accettabili (descritti nelle specifiche sull’affidabilità e la

sicurezza) sono detti fail-controlled. Ad esempio, siffatti componenti possono essere tali da

bloccare l’output invece di presentare valori errati, oppure possono essere in grado di

fallire solo in modo consistente. Si definisce allora sistema fail-halt o fail-stop un

componente in grado di fallire solo in modalità halted. Ciò di solito ha lo scopo di evitare

quanto più possibile qualsiasi conseguenza negativa su altri sistemi o operatori umani. Un

sistema fail-safe, infine, dovrebbe garantire che i fallimenti e le loro conseguenze siano

quanto più ridotti possibile. Fail-safe devono essere, ad esempio, le applicazioni il cui

fallimento implica il sorgere di situazioni pericolose per gli utenti (come applicazioni radar

per il controllo del traffico aereo o software per apparecchiature mediche).

Page 23: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

16

1.2.2 Errori

Un errore è la parte dello stato totale di un sistema che può (o meno) determinare

l’insorgere di un fallimento, nel caso la situazione anomala riesca a propagarsi sino

all’interfaccia utente.

Poiché i sistemi sono costituiti da una serie di componenti interagenti, lo stato totale può

essere definito come la combinazione degli stati delle singole unità. Questa definizione

implica che:

- un guasto all’interno di uno specifico componente può generare errori in più unità del

sistema. In tal caso si parla di multiple related error mentre, se il fault riguarda un

unico componente, gli errori provocati si definiscono single error;

- un fault può originare un errore all’interno dello stato di un componente senza che

occorra un fallimento nel servizio ad alto livello. Ciò avviene quando lo stato esterno

dell’unità compromessa non fa parte dello stato esterno del sistema.

L’occorrenza di un fallimento in presenza di un errore dipende, in particolare, da due

fattori:

- la struttura del sistema e, soprattutto, la natura di ogni forma di ridondanza;

- il comportamento del sistema.

Per quanto concerne il primo punto, si deve tener presente che non esiste soltanto la

cosiddetta ridondanza protettiva (introdotta per fornire una certa tolleranza ai guasti) ma

anche una forma di ridondanza non intenzionale (perché è spesso difficile, se non

impossibile, progettare un sistema senza alcuna ridondanza) che può avere effetti simili

alla prima. Riguardo al secondo punto, invece, può accadere che la parte dello stato che

contiene l’errore non divenga mai necessaria al servizio o che l’errore stesso sia

sovrascritto prima che ingeneri il fallimento.

Una classificazione conveniente degli errori può essere basata sulle categorie di

fallimenti che essi sono in grado di provocare. È cioè possibile distinguere errori:

- di tempo e di valore;

- rilevati e latenti;

Page 24: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

17

- consistenti ed inconsistenti

- catastrofici e benigni.

1.2.3 Guasti

Come mostra la figura 1.6, tutti i guasti che possono interessare un sistema durante il

suo intero ciclo di vita sono classificati in [3] in base ad otto punti di vista, detti classi di

fault elementari.

Figura 1.6: classi di fault elementari.

Se fossero possibili tutte le combinazioni delle 8 classi, potrebbero essere derivate ben 256

differenti classi di fault combinate. Ovviamente, però, non tutti i criteri sono applicabili ad

ognuna delle classi di guasti (ad esempio, i fault naturali non possono essere classificati in

Page 25: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

18

base ad obiettivi, intenti e capacità). È così possibile identificare solo un sottoinsieme di

tutte le combinazioni, come le 31 mostrate in figura 1.7 con i relativi esempi.

Figura 1.7: classi di fault combinate.

Le classi combinate appartengono a tre gruppi parzialmente sovrapposti:

- guasti di sviluppo, che includono tutti quei fault nati in fase di sviluppo del sistema;

- guasti fisici, cioè quelli che riguardano l’hardware;

- guasti di interazione, che includono tutti i fault esterni.

I fault naturali sono guasti fisici (cioè hardware) causati da fenomeni naturali e senza la

partecipazione umana. Ad esempio, i difetti fisici sono fault naturali che si originano

durante lo sviluppo. Durante la fase operativa, i fault naturali possono essere sia interni,

Page 26: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

19

cioè dovuti al deterioramento fisico di alcuni componenti, che esterni, ossia causati da

processi naturali. Questi ultimi si originano al di fuori dei confini del sistema e riescono a

penetrarvi, ad esempio attraverso radiazioni elettromagnetiche, picchi di potenza elettrica,

cambiamenti di temperatura, ecc..

La definizione dei fault dovuti all’uomo (che possono essere sia hardware che software)

include quelli causati dalla mancanza di intervento quando quest’ultimo sarebbe

necessario, cioè i cosiddetti guasti per omissione. Inoltre, i suddetti fault possono essere

classificati in due gruppi, a seconda dello scopo dell’intervento umano:

- guasti maliziosi, introdotti volontariamente durante l’uso del sistema o anche durante

il suo sviluppo (allo scopo di far nascere situazioni di emergenza in fase operativa)

per alterarne lo stato, provocare una sospensione del servizio o per accedere a

informazioni riservate;

- guasti non maliziosi, causati in maniera inconsapevole.

I fault non maliziosi possono poi essere ulteriormente classificati, a seconda della

consapevolezza degli attori, in:

- guasti non deliberati, dovuti ad errori o ad azioni di sviluppatori, utenti e

manutentori di cui questi ultimi ignorano le conseguenze;

- guasti deliberati, che sono causati da decisioni sbagliate ma volontarie.

Un’ulteriore particolarizzazione dei fault non maliziosi può essere fatta considerando le

capacità di sviluppatori ed utenti che possono provocare:

- guasti accidentali, cioè originati da incidenti e senza l’esplicita volontà della persona

coinvolta;

- guasti da incompetenza, dovuti alla poca conoscenza che gli sviluppatori o gli

utilizzatori hanno del dominio del problema e del sistema stesso, oppure alla scarsa

attenzione che questi pongono su taluni fattori (che, ad esempio, conducono a scelte

di progetto infelici).

I fault di interazione sono guasti operativi (cioè che occorrono durante il normale

funzionamento del sistema) che possono essere sia dovuti all’uomo che a cause naturali.

Page 27: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

20

Essi sono comunque ingenerati da alcuni elementi dell’ambiente d’uso che interagiscono

con l’apparato (quindi si tratta di guasti esterni) in maniera scorretta. A volte possono

essere definiti di interazione i cosiddetti errori di configurazione dovuti al settaggio

sbagliato di parametri in grado di influenzare la sicurezza, la gestione della memoria e

delle reti, la comunicazione fra le varie componenti del sistema, ecc.. Una caratteristica

comune dei guasti di interazione è che essi sono favoriti dalla presenza intrinseca di una

qualche vulnerabilità, cioè di un fault interno capace di abilitarne uno esterno in grado di

danneggiare il sistema.

Un’ultima classificazione dei fault riguarda la loro persistenza. Relativamente ai guasti

hardware è possibile distinguere:

- guasti permanenti, stabili e continui nel tempo;

- guasti transienti, legati a momentanee condizioni ambientali e che scompaiono

definitivamente senza la necessità di alcuna operazione di ripristino;

- guasti intermittenti, che si verificano in corrispondenza di particolari condizioni

ambientali e scompaiono senza alcuna azione di riparazione per poi ricomparire.

Per quanto concerne il software, non esiste la distinzione tra guasti intermittenti e transienti

poiché tutti i guasti software si attivano in corrispondenza di precise condizioni, più o

meno complesse. Ne deriva che questi fault sono permanenti, nel senso che ciascun bug

rimane nel codice (finché non è eventualmente corretto) anche se viene attivato (e quindi

percepito dall’utente) solo da precise condizioni.

1.2.3.1 Guasti software

Gray [4], al fine di definire un meccanismo di fault tolerance, presenta preliminarmente

un modello di fallimenti software basato sulla cosiddetta ipotesi Bohrbug/Heisenbug. È

noto che molti guasti hardware sono soft, cioè di natura transitoria, e che ad essi si può (in

qualche misura) porre rimedio con metodi standard basati su checksum, correzione degli

errori di memoria, ritrasmissione ecc.. Tali tecniche riescono ad innalzare il MTBF di una

Page 28: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

21

quantità che si stima vari fra 5 e 100 unità temporali. Gray afferma che, similmente a ciò

che avviene per l’hardware, anche molti fault software sono soft: è infatti esperienza

comune che, riavviando semplicemente un’operazione dopo un crash, questa spesso non

fallisce una seconda volta. Tale ipotesi, apparentemente paradossale, discende dal fatto che

i bug sistematici vengono tipicamente identificati e risolti durante le fasi di debugging e

testing del software.

Guasti di quest’ultimo tipo vengono chiamati Bohrbug. Essi (il cui nome deriva dall’atomo

di Bohr) sono hard, cioè “solidi”: si tratta spesso di fault permanenti di progetto che hanno

natura abbastanza deterministica. Tale caratteristica implica che i Bohrbug sono facili da

identificare con tecniche standard durante le fasi di debugging e collaudo (oppure

addirittura di deployment).

Se si considera un software industriale, dopo il progetto, le revisioni, la fase di quality

assurance, i test di tipo alpha e beta, ecc., si può ritenere che la maggior parte dei Bohrbug

siano stati eliminati. I guasti residui, tipicamente rari se le fasi precedenti sono state

condotte con rigore, saranno allora correlati a condizioni hardware (fault hardware rari o

transienti, problemi di incompatibilità, questioni legate ai driver, ecc.), condizioni limite

(overflow e underflow, carichi eccessivi, ecc.) o race condition1. In siffatte circostanze, il

riavvio del programma ricrea tipicamente un ambiente molto diverso da quello del

fallimento che, in numerosi casi, conduce al normale funzionamento dell’applicazione. Ai

fault che esibiscono il comportamento appena descritto si dà il nome di Heisenbug (dal

principio di indeterminazione omonimo). Essi possono eludere i sistemi di collaudo per

anni poiché, a differenza dei Bohrbug, una stessa operazione di testing può perturbare

l’ambiente operativo al punto da far sparire l’Heisenbug. Le condizioni di attivazione di un

Heisenbug si presentano, infatti, in maniera molto rara e sono difficilmente riproducibili

proprio perché questi fault sono fortemente dipendenti dall’ambiente operativo. Recenti

studi hanno evidenziato che il 70% degli errori sono di tipo transiente e sono causati

1 Si ha una race condition, o corsa critica, quando in un programma, in cui due o più processi condividono

delle risorse comuni, l’esecuzione del programma stesso è influenzata dal modo in cui i processi vengono schedulati. Questo problema viene gestito mediante la mutua esclusione (si permette ad un solo processo alla volta di accedere alla risorsa condivisa).

Page 29: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

22

principalmente da race condition e da problemi di sincronizzazione.

Taluni autori definiscono gli Heisenbug come un sottoinsieme di un classe di fault ben più

vasta, i Mandelbug [5, 6]. Questi sono fault che possono indurre il software ad esibire un

comportamento caotico e non deterministico rispetto all’occorrenza e non occorrenza di

fallimenti. La loro attivazione e le modalità di propagazione seguono dinamiche complesse

in almeno uno dei seguenti modi:

- con lunghi ritardi tra l’attivazione del fault e l’occorrenza finale del fallimento. Se il

sistema attraversa differenti stati di failure durante la propagazione dell’errore,

diventa difficile identificare le azioni dell’utente che realmente hanno attivato il fault

e causato il fallimento. La semplice ripetizione dei passi eseguiti in breve tempo,

prima dell’occorrenza del fallimento, può non condurre alla sua riproduzione;

- con un comportamento che dipende fortemente da alcuni elementi dell’ambiente,

quali il sistema operativo, l’interazione con altre applicazioni, o l’hardware.

Poiché gli Heisenbug sono guasti software che cambiano il proprio comportamento quando

vengono esaminati o isolati (cioè quando muta l’ambiente operativo), essi risultano un

sottotipo di Mandelbug.

Per quel che riguarda le tecniche utili per la correzione dei bug software [5, 6] è stato

già detto che metodi di progettazione, debugging e testing robusti conducono quasi sempre

all’eliminazione dei Bohrbug. Per i Mandelbug si può sfruttare l’assunto che il reboot del

sistema risolve spesso il problema, accoppiando quest’ultimo con approcci di

checkpointing, ossia tecniche che consentono il salvataggio periodico dello stato

dell’applicazione in memoria stabile. Con metodi siffatti, dopo il fallimento è possibile

riavviare l’applicazione, portandola nell’ultimo stato senza errori memorizzato. Un

secondo approccio consiste nell’utilizzare la replicazione, ossia nel ridondare le risorse del

sistema. Due applicazioni identiche che girano su diverse istallazioni dello stesso sistema

operativo possono, infatti, non esibire gli stessi fallimenti. Se si suppone che tutti i

Bohrbug risultano eliminati dopo il testing, allora i guasti dei due programmi replicati

possono ritenersi legati all’ambiente operativo e saranno, dunque, dei Mandelbug. Il

Page 30: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

23

confronto fra le configurazioni hardware e software dei due sistemi, al momento di un

fallimento in uno dei due, può così aiutare a comprendere le cause del problema.

1.3 Metodi per migliorare la dependability del software

Durante le fasi del ciclo di vita del software si può cercare di assicurare una maggiore

affidabilità al prodotto finale, seguendo differenti approcci per la gestione dei guasti [3]:

- fault prevention;

- fault tolerance;

- fault removal;

- fault forecasting.

La prevenzione dei guasti, considerata come un miglioramento del processo di sviluppo

che ha il fine di ridurre il numero di fault introdotti nel sistema prodotto, è una parte

importante dell’ingegneria in generale. La prevenzione dei bug software si attua, ad

esempio, applicando le buone regole imposte dall’ingegneria del software, quali

l’information hiding, la modularità, l’uso di linguaggi di programmazione tipizzati, ecc..

La tolleranza ai guasti (figura 1.8), che ha lo scopo di evitare i fallimenti, si basa sulla

rilevazione degli errori e sul ripristino del sistema. Per quel che riguarda la prima fase,

essa può essere espletata in maniera concorrente (cioè durante la normale erogazione del

servizio) o preventiva (quando il servizio viene sospeso alla ricerca dei guasti latenti).

Il ripristino, invece, si basa sulla gestione degli errori (error handling), che ha lo scopo di

eliminare gli errori dallo stato del sistema, e sulla gestione dei guasti (fault handling), che

serve ad evitare che uno stesso fault sia nuovamente attivato. Questa seconda fase è seguita

di solito dalla cosiddetta manutenzione correttiva, che ha lo scopo di rimuovere i fault

isolati nella fase di handling. La gestione degli errori può essere implementata attraverso

forme di rollback (si porta il sistema all’ultimo checkpoint, ossia all’ultimo stato senza

errori salvato), rollforward (si assegna al nuovo stato del sistema l’ultimo stato senza

errori) o compensazione (ci si serve della ridondanza per mascherare un errore corrente).

Page 31: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

24

Le prime due tecniche vengono invocate on demand, dopo la fase di rilevazione degli

errori. La compensazione, invece, può essere applicata sia on demand che

sistematicamente, ad intervalli di tempo predefiniti o scanditi da eventi, ed

indipendentemente dall’occorrenza di un errore. L’error handling on demand seguita dalla

fault handling formano la strategia di tolleranza ai guasti chiamata brevemente detection

and recovery, mentre la cosiddetta fault masking deriva dall’uso sistematico della

compensazione.

Figura 1.8: metodi di fault tolerance.

Tra le tecniche per la gestione degli errori va annoverata anche la software rejuvenation

(cfr. paragrafo 1.6). Nel caso dell’aging, in particolare, la rilevazione è effettuata

solitamente misurando la disponibilità delle risorse (ad esempio il livello di memoria

libera) e stimando il loro tempo di esaurimento (TTE – cfr. paragrafo 1.5.2). In molti casi,

comunque, la rejuvenation avviene senza la rilevazione degli errori (cioè periodicamente)

al fine di rimuovere questi ultimi, se presenti, soltanto sulla base del TTE stimato.

Page 32: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

25

La gestione dei guasti, infine, si può comporre delle seguenti fasi:

- diagnosi, che consiste nell’identificare e registrare le cause degli errori in termini di

locazione e tipologia;

- isolamento, che implementa l’esclusione logica o fisica del componente difettoso, in

modo da mascherare il guasto;

- riconfigurazione, che si occupa di ridistribuire i compiti dei componenti guasti ad

unità di riserva non fallite;

- reinizializzazione, che consiste nell’aggiornamento e nella registrazione della nuova

configurazione.

La rimozione dei guasti può avvenire durante la fase di sviluppo o durante quella

operativa. Nel primo caso, essa consiste di tre passi: la verifica, la diagnosi e la correzione.

La verifica serve a controllare che il sistema soddisfi alcune proprietà di interesse. In caso

negativo si passa alla diagnosi, per identificare le cause dell’anomalia, e successivamente

alla correzione dell’errore. Dopo quest’ultima fase, dovrebbe essere ripetuto lo step di

verifica, per assicurarsi di non aver introdotto altri fault con la correzione. La validazione

può essere statica o dinamica, a seconda del fatto che avvenga in maniera formale o

coinvolga il funzionamento reale del sistema.

L’eliminazione dei guasti durante l’uso consiste nella cosiddetta manutenzione correttiva o

preventiva. La prima cerca di rimuovere i guasti che hanno condotto ad un errore rilevato,

mentre la seconda ha lo scopo di identificare ed eliminare quei fault non segnalati che

possono risultare in un errore durante il normale funzionamento del sistema.

La fault forecasting, infine, è condotta per implementare una valutazione del

comportamento del sistema per quel che riguarda l’occorrenza dei guasti. Tale stima consta

di due aspetti:

- la valutazione qualitativa o ordinale, che cerca di identificare e classificare i failure

mode oppure le combinazioni di eventi in grado di condurre il sistema al fallimento;

- la valutazione quantitativa o probabilistica, che prova a determinare il punto fin

dove alcune proprietà di interesse (dette misure) sono soddisfatte.

Page 33: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

26

La valutazione quantitativa si può basare su cosiddetti benchmark di affidabilità, ossia su

procedure di misura del comportamento di un sistema in presenza di fault. Il fine di tali

metodologie consiste nella caratterizzazione degli attributi di dependability, nonché nella

scelta comparativa delle possibili soluzioni.

1.4 Software aging

Come precedentemente affermato, non è possibile produrre software bug-free. Ne

deriva che assicurare una certa dependability alle applicazioni implica la necessità di

impiegare tecniche di fault tolerance in fase operazionale. Per sistemi caratterizzati da

requisiti critici di affidabilità, queste possono includere metodologie per l’analisi

dell’aging e per la relativa rejuvenation.

A tal proposito, si definisce software aging [7] quel fenomeno che riduce l’affidabilità

del software, determinandone una lenta e progressiva degradazione delle prestazioni

oppure improvvisi stalli o crash, causato nella maggior parte dei casi da esaurimento delle

risorse del sistema operativo, frammentazione, corruzione di dati ed accumulo di errori

numerici durante un lungo periodo di tempo. La definizione di software aging può

sembrare un’assurdità se si considera il software un prodotto matematico: un teorema,

infatti, se risulta errato oggi, doveva necessariamente esserlo anche al momento della sua

produzione. In realtà moltissimi sono gli aspetti che rendono il comportamento delle

applicazioni più diverse variabile del tempo e, a volte, non predicibile.

I sistemi maggiormente colpiti da tale fenomeno risultano quelli long running, cioè quelli

che restano in esecuzione per lunghi periodi di tempo e tendono a mostrare un tasso di

fallimenti via via crescente. Per tale motivo, il software aging non si osserva quasi mai in

programmi di utilizzo comune ma in applicazioni specializzate, che spesso sono

caratterizzate da requisiti critici di affidabilità e sicurezza.

Bisogna sottolineare che i fault causati dall’aging non riguardano l’obsolescenza dei

sistemi software (dovuta ai cambiamenti apportati nel tempo al sistema stesso oppure ad

Page 34: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

27

interventi errati di manutenzione), bensì fattori come memory leaking, memory bloating,

lock su file non rilasciati, frammentazione dei dischi ed accumulo di errori di round-off.

Questa assunzione risulta relativamente giovane se si pensa che Parnas [8], nel 1998,

attribuiva le cause dell’aging all’incapacità dei gestori del software di implementare

modifiche in grado di sopperire ai cambiamenti richiesti (tecnologici e funzionali) o

all’inadeguatezza della manutenzione.

Se si considera l’invecchiamento del software, la classificazione dei bug presentata nel

paragrafo 1.2.3.1 va modificata includendo i cosiddetti aging-related fault [9,10] (figura

1.9). Questi ultimi possono appartenere sia alla categoria dei Bohrbug sia a quella dei

Mandelbug, a seconda che risultino deterministici, e quindi riproducibili, oppure

transienti.

Figura 1.9: aging-related bugs.

A titolo di esempio, si considerino un bug che causi un progressivo esaurimento delle

risorse in maniera deterministica ed uno che provochi un esaurimento delle risorse con un

andamento difficilmente predicibile e riproducibile. Il primo fault può allora essere

considerato un aging-related Bohrbug mentre il secondo un aging-related Mandelbug.

Per quel che riguarda i metodi utili ad eliminare i bug collegati all’aging, si deve tener

presente che il tasso di fallimenti di questo genere tende ad aumentare al crescere del

tempo in cui il sistema resta running. Per tale ragione, l’approccio più comune, che prende

il nome è di software rejuvenation (cfr. paragrafo 1.6), è di tipo proattivo e consiste nel

ripristinare periodicamente lo stato del sistema.

Page 35: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

28

1.5 Metodi per l’analisi dell’aging

In letteratura sono state introdotte due tipologie di approcci per studio del software

aging: una di tipo analitico e l’altra basata sulla misurazione del degrado delle risorse di

sistema. Il primo criterio è detto analytical modeling e si fonda sull’uso di modelli formali

come, ad esempio, le reti di Petri e le catene Markoviane. Il secondo metodo di studio è

definito measurement-based, in quanto basato su una metodologia empirica ed eseguito

attraverso un’analisi statistica dei dati relativi al sistema sotto osservazione.

L’approccio model based consente di determinare una pianificazione ottimale della fase di

rejuvenation, che però dipende fortemente dai dati che sono stati rilevati nel sistema

stesso. È quindi necessario che il software ed il suo comportamento (anche in caso di

fallimento) siano ben noti a priori, in maniera tale da poter effettuare un’analisi

comparativa tra il normale comportamento del sistema e quello in caso di guasti.

L’approccio measurement based, invece, consente una stima piuttosto affidabile del TTE

(cfr. paragrafo 1.5.2) ma spesso non rende possibile la determinazione di una

schedulazione ottima di rejuvenation.

È immediato quindi osservare che il primo metodo può essere effettivamente applicato

solo se si dispone di una notevole quantità di informazioni sul comportamento del sistema

nei confronti dei guasti. Il secondo, invece, va preso in considerazione quando non si è in

grado di utilizzare uno dei formalismi di cui al paragrafo 1.5.1 per modellare il

comportamento del sistema.

Oltre ai due approcci appena definiti, è talvolta proposto un meccanismo più semplice,

che può essere chiamato time-based. Esso prevede la periodica esecuzione della tecnica di

rejuvenation ad intervalli di tempo regolari. Se il periodo tra due esecuzioni successive è

relativamente breve, il livello di protezione nei confronti dell’aging è sicuramente molto

elevato ma il costo dovuto all’applicazione frequente della tecnica di rejuvenation risulta

troppo oneroso (ed il più delle volte inutile). Se la frequenza di esecuzione della

rejuvenation è al contrario modesta, allora possono verificarsi fallimenti imprevisti, con

conseguenze anche catastrofiche. Ne deriva che tale tecnica non risulta essere molto

Page 36: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

29

adeguata, in quanto prescinde completamente dall’analisi del funzionamento del sistema, a

differenza degli approcci analitici e basati su misure che saranno approfonditi nei paragrafi

successivi. La rejuvenation dovrebbe essere applicata, cioè, solo a valle dell’analisi

dell’aging, condotta al fine di individuare le cause e la gravità dell’invecchiamento, in

modo da massimizzare gli effetti di un eventuale intervento proattivo.

1.5.1 Analytical modeling

Questo primo approccio si basa sull’utilizzo di modelli matematici che consentono di

definire una rappresentazione del degrado del sistema sotto osservazione. In base ad un

insieme di parametri, forniti in input a tali modelli, è possibile ottenere una schedulazione

ottimale degli interventi di rejuvenation.

Il suddetto approccio si basa principalmente sull’utilizzo del modello SMP (semi-

Markovian process), e sul semi-Markov reward process. Tralasciando i mezzi analitici per

la risoluzione dei modelli, lo svantaggio di queste metodologie risiede nel fatto che è

richiesta comunque la conoscenza di un insieme completamente ordinato di osservazioni

sul sistema.

Il modello base di software rejuvenation è stato proposto da Huang et al. in [7].

Sebbene esso preveda una formulazione del problema attraverso una catena di Markov

tempo continua, i risultati possono essere estesi in maniera tale da ottenere una struttura

matematica più generale. In particolare, il modello di software rejuvenation può essere

visto come un processo semi-Markoviano. In figura 1.10 si riporta il diagramma a stati di

tale modello, in cui gli stati sono così definiti:

- stato 0: molto robusto;

- stato 1: con probabilità di failure;

- stato 2: con failure;

- stato 3: software rejuvenation.

Page 37: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

30

Figura 1.10: modello semi-Markoviano.

Lo stato 0 del modello può essere visto come la fase in cui il software si trova

immediatamente dopo il rilascio oppure a valle di eventuali operazioni di ripristino. Dopo

un periodo di tempo casuale, esso comincia ad invecchiare: tale fase corrisponde allo stato

1 e la probabilità di eventuali failure diviene maggiore di zero non appena vi si giunge.

Bisogna quindi prevedere operazioni che siano in grado di prevenire o, eventualmente,

riparare i probabili fallimenti che si verificheranno sul prodotto software. Per questo

motivo, periodicamente, dovrebbero essere effettuate operazioni di ripristino in maniera da

riportare il sistema nello stato 0. Nel caso in cui un fallimento si verifichi in un istante

precedente rispetto alle operazioni di ripristino, bisogna intervenire attraverso una

riparazione immediata del software (stato 2 del diagramma), che sarà completata dopo un

lasso di tempo casuale. In caso contrario, viene attivata la software rejuvenation (ad

intervalli di tempo regolari), corrispondente allo stato 3 del modello.

A questo punto è lecito porsi qualche domanda. Quando la riparazione è completata

successivamente ad un failure, il sistema software è realmente rinnovato? Probabilmente,

in alcuni casi, la risposta è no. Se si distingue la software rejuvenation dalla software

repair, un’addizionale software rejuvenation potrebbe infatti essere necessaria dopo la

riparazione. Ad esempio, il riavvio del sistema successivamente ad una riparazione

potrebbe procurare una certa pulizia ed un ripristino dell’esecuzione del processo dallo

stato di checkpoint. In figura 1.11 è mostrato, allora, il diagramma di transizione

modificato che è stato proposto in [11]. Secondo tale approccio, la software rejuvenation è

Page 38: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

31

eseguita sia dopo il completamento della riparazione che ad intervalli di tempo prestabiliti

(come già previsto dal modello precedente).

A partire dalla catena semi-Markoviana modificata, è stato sviluppato un algoritmo non

parametrico per stimare la schedulazione ottima di software rejuvenation che massimizza

la disponibilità del sistema. Tale algoritmo prevede la massimizzazione della probabilità

relativa al tempo di permanenza nello stato stabile del diagramma (stato 0), assumendo

che il tempo medio per eseguire una riparazione a seguito di un guasto sia strettamente

maggiore del tempo medio di rejuvenation.

Figura 1.11: modello semi-Markoviano modificato.

Uno dei problemi più rilevanti, nelle applicazioni pratiche, è la velocità di convergenza per

la stima del tempo di software rejuvenation ottimale. In particolare, per poter effettuare

una previsione adeguata, bisogna considerare un elevato numero di campioni,

rappresentanti ognuno gli istanti di tempo in cui si è verificato un failure.

Dalla figura 1.12 è possibile evincere come, nel caso del secondo modello proposto, il

periodo di schedulazione ottima per la software rejuvenation in funzione del tempo medio

Page 39: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

32

di failure del sistema sia sempre inferiore a quello del primo modello.

Figura 1.12: confronto tra i modelli semi-Markoviano e semi-Markoviano modificato.

Un secondo approccio analitico si basa sulle reti di Petri ed utilizza le Markov

Regenerative Stochastic Petri Net (MRSPN) [12]. Una difficoltà nella modellazione di un

sistema stocastico deriva dal fatto che l’intervallo di tempo di rejuvenation è deterministico

e ciò rende il sistema non Markoviano. Le reti di Petri (Stochastic Petri Net – SPN), con la

loro notevole flessibilità, vengono utilizzate allora per una modellazione quantitativa di un

sistema.

Il software si trova inizialmente in uno stato “robusto” in cui la probabilità di fallimenti

teoricamente è pari a zero. Durante la sua messa in esercizio, il prodotto comincia ad

invecchiare e transita in un nuovo stato (come visto anche nel precedente modello). A

questo punto, il sistema lavora normalmente ma la probabilità di fallimenti è maggiore di

zero e tende ad aumentare con il passare del tempo.

In figura 1.13, lo stato robusto è raffigurato dal punto Pup. La transizione Tfprob modella

l’aging del software: quando essa ha luogo, il sistema entra nello stato Pfprob in cui c’è

probabilità di failure maggiore di zero. La transizione Tdown modella i crash del software.

Durante il ripristino (cioè finché Tup è abilitata), ogni altra attività è sospesa (nel

diagramma attraverso l’arco inibitore dal punto Pdown a Tclock). La transizione Tclock modella

l’intervallo di rejuvenation ed è abilitata da Tfprobe: una volta entrati in tale fase, il sistema

giunge nello stato di rejuvenation Prej.

Page 40: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

33

Figura 1.13: modello MRSPN di software rejuvenation.

Al termine di questa procedura, la rete deve essere re-inizializzata e riportata negli stati di

Pup e Pclock. Se il software è in uno stato robusto quando scatta Tclock, allora, dopo che la

rejuvenation è completata, scatta Trej1 per riportare la rete nello stato iniziale.

Tale modello rappresenta una rete SPN che ricade all’interno della classe delle MRSPN.

Come nel caso dell’approccio proposto in [11], studiando una rete di questo tipo può essere

definita una schedulazione ottima di software rejuvenation.

La limitazione più evidente del modello MRSPN consiste nel fatto che esso studia l’aging

soltanto in funzione del tempo, ignorando del tutto il carico di lavoro applicato alla

macchina.

1.5.2 Measurement-Based Approach

L’approccio measurement-based è fondato principalmente sul monitoring delle risorse

di sistema, in base alle quali è possibile fornire un insieme di informazioni sotto forma di

indicatori di aging. Questa metodologia si articola in due fasi distinte:

Page 41: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

34

- monitoring e raccolta periodica dei dati relativi agli attributi che possono aiutare a

valutare lo stato di salute del sistema;

- analisi delle informazioni reperite, al fine di quantificare l’effetto dell’aging sul

sistema sotto osservazione, stimando la metrica del Time To Exahustion (TTE),

indicante il tempo in cui una determinata risorsa si esaurisce completamente.

A seconda dei parametri scelti per lo studio, si parla di workload-independent aging

analysis [13, 14] e workload-based aging analysis [13, 15].

Nel primo caso i dati prescelti per l’analisi riguardano esclusivamente lo stato delle risorse

del sistema (memoria libera/occupata, spazio di swap libero/usato, etc.). A partire da tali

informazioni, reperite in un tempo relativamente lungo la cui durata dipende dal contesto

applicativo, si verifica la presenza di un trend di aging attraverso opportune tecniche di

test (tra cui quella di Mann-Kendall). Se la presenza del trend è significativa, con

strumenti atti alla decorrelazione dei dati reperiti e tramite algoritmi di regressione, è

possibile risalire alle probabili cause del software aging all’interno del sistema.

L’analisi di aging di tipo workload-based è impostata, invece, sull’idea secondo la quale il

fenomeno del software aging viene influenzato anche dal carico di lavoro impartito al

sistema. Difatti, il consumo di risorse dipende direttamente dalla quantità di operazioni e

dal carico imposto da ognuna di queste. L’obiettivo è dunque quello di stimare la

correlazione tra workload applicato, availability e perfomability del sistema. Ovviamente,

in tal caso, i risultati possono essere ritenuti validi soltanto se si suppone che il workload

rimanga pressoché costante nel tempo, per tutta la durata dell’esperimento. Questo tipo di

analisi prevede il tracciamento dei parametri che caratterizzano il sistema, in maniera tale

da monitorare le informazioni a livello del SO che descrivono il carico imposto. Ad

esempio, si può scegliere di monitorare le attività di I/O, il numero di system call invocate,

così come la frequenza di allocazione in memoria.

L’approccio workload-based richiede una fase di analisi articolata, in quanto l’esistenza

del trend va spiegata in base ai parametri di workload applicati. Un esempio, a tal

proposito, è presentato in [15], dove è stata definita una fase preliminare in cui vengono

Page 42: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

35

identificati i cosiddetti stati di workload, ossia gli stati in cui il sistema è caratterizzato da

valori dei parametri di carico “simili”. Successivamente si individuano le probabilità di

transizione da uno stato all’altro, modellando il sistema come un processo semi-

Markoviano. Il calcolo del trend di aging può quindi essere eseguito per ogni stato di

workload, consentendo la stima del TTE in funzione di quest’ultimo. Il procedimento può

essere schematizzato come segue (figura 1.14):

- definizione dell’ambiente/sistema che caratterizza l’esperimento;

- reperimento dei dati di interesse del sistema;

- scelta dei parametri di workload più rappresentativi;

- cluster analysis, mirata all’identificazione degli stati di workload;

- definizione della matrice delle probabilità di transizione tra gli stati;

- fitting della Sojourn Time Distribution, ovvero della distribuzione statistica che

caratterizza il tempo speso dal sistema in ogni stato;

Figura 1.14: esempio di approccio measurement-based.

Page 43: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

36

- assegnazione di un costo per ciascuna risorsa monitorata, in ognuno degli stati di

workload individuati. Per ogni stato i e per ogni risorsa j, si definisce il reward rate

rij come la variazione stimata del consumo della risorsa i nello stato j;

- calcolo dell’expected steady reward rate, che può essere considerato come la

frequenza di consumo di ogni risorsa, mediata su tutti gli stati di workload.

1.6 Software rejuvenation

La rejuvenation [5, 6, 7, 10] può essere definita come un periodico e preventivo riavvio

di un’applicazione, che consente di “ripulire” lo stato interno del sistema. L’intervallo di

rejuvenation è basato essenzialmente sulla longevità dell’applicazione in esecuzione. Il

riavvio del sistema comporta il cleaning delle strutture dati in memoria, nonché la

rigenerazione dei processi nello stato iniziale o in uno precedente di checkpoint. Quindi, si

può definire la rejuvenation come un rollback preventivo e periodico di applicazioni long

running, che cerca di evitare eventuali fallimenti futuri.

Dalla definizione si deduce che la periodicità è un requisito essenziale per la corretta

riuscita del ringiovanimento. L’altra caratteristica fondamentale è che tale tecnica deve

essere eseguita in maniera preventiva, ovvero prima che si possano presentare dei fault, o

comunque prima che l’ambiente di sistema degradi a causa del graduale esaurimento delle

risorse.

La rejuvenation può essere espletata a vari livelli di granularità, ad esempio a livello di

sistema o di applicazione. Un esempio del primo caso consiste nel riavvio dell’hardware.

Di solito si utilizzano, comunque, delle tecniche di rejuvenation selettive (a livello di

applicazione), le quali individuano un componente o un sottosistema specifico su cui è

necessario intervenire. In tal modo è possibile, eventualmente, condurre operazioni di

rejuvenation parziali minimizzando i costi relativi a tale fase del ciclo di vita del software.

Un esempio di rejuvenation selettiva è effettuata dal garbage collector della JVM. Tale

componente consente la gestione automatica della memoria, garantendo l’eliminazione

Page 44: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

37

degli oggetti o dei dati che sono stati allocati e non sono più utilizzati da nessun altro

processo/componente all’interno dell’applicazione. Un altro esempio di tecnica selettiva

può essere individuata nell’utilità di deframmentazione dei dischi, in quanto il fenomeno

della frammentazione può essere causa di aging, poiché favorisce il degrado delle

prestazioni dovuto all’aumento dei tempi di ricerca (seek time) e di latenza.

Non sempre, tuttavia, si possono applicare modalità parziali, ad esempio nel caso di

applicazioni software poco modulari oppure quando la rejuvenation selettiva non produce

pienamente gli effetti desiderati sul sistema.

La software rejuvenation può essere espletata seguendo due criteri distinti [10]:

- approccio a ciclo aperto, cioè senza alcun tipo di feedback da parte del sistema dopo

la rejuvenation stessa. In tal caso, la schedulazione degli interventi può essere basata

solo sul tempo trascorso (implementando, cioè, una rejuvenation periodica) e/o sul

numero istantaneo di job in carico al sistema;

- approccio a ciclo chiuso, secondo cui gli interventi sono basati sulle informazioni

inerenti alla salute del software. Quest’ultimo viene così monitorato continuamente

(nella pratica, ad intervalli di tempo deterministici molto brevi), in modo da

collezionare i dati relativi all’uso delle risorse e alle attività del sistema. Come visto

nel precedente paragrafo, tali informazioni sono poi analizzate al fine di stimare il

TTE delle risorse sotto osservazione. La previsione può essere basata sul tempo, sul

tempo e sul workload oppure sul tasso di fallimenti.

L’approccio a ciclo chiuso può essere ulteriormente classificato a seconda che l’analisi

avvenga off-line oppure on-line. Nel primo caso, ci si basa sui dati collezionati in un

periodo di tempo più o meno lungo (ad esempio, in settimane o mesi). Questa metodologia

funziona particolarmente bene se il sistema ha un comportamento che può essere

considerato deterministico. L’approccio a ciclo chiuso on-line, invece, effettua l’analisi dei

dati collezionati ad intervalli di tempo deterministici e, ad ogni nuova disponibilità delle

informazioni del sistema, stima il tempo di rejuvenation. Tale metodologia è più generale

e risulta applicabile anche ai sistemi con dinamiche comportamentali molto complesse,

Page 45: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

38

che non possono essere facilmente determinate. In tal caso, il comportamento futuro del

sistema viene predetto basandosi sui valori correnti degli attributi collezionati e su quelli

passati opportunamente pesati.

La classificazione degli approcci di rejuvenation appena descritta è schematizzata in figura

1.15.

Figura 1.15: approcci di software rejuvenation.

Page 46: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

39

Capitolo 2 Software aging nei sistemi operativi

Gli studi riguardanti il fenomeno di aging, come si è già detto, sono relativamente

giovani ed incentrano il proprio interesse su applicazioni disparate (Java Virtual Machine,

application server, librerie, ecc.) trascurando quasi del tutto l’impatto del fenomeno sui

sistemi operativi (SO). Tuttavia, si deve tener presente che il SO si configura come arbitro

di qualsiasi calcolatore, gestendo e distribuendo le risorse computazionali fra i vari

processi in esecuzione. Ne deriva che, se si considera l’invecchiamento come una minaccia

alla dependability del software long running, non si può prescindere dell’analisi dello

stesso nei SO. In sistemi life critical, infatti, un malfunzionamento del sistema operativo

può avere effetti catastrofici, allo stesso modo (o anche con conseguenze peggiori) di un

fallimento del software applicativo. È dunque utile comprendere le cause che possono

indurre un sistema operativo ad invecchiare, nonché le dinamiche ed i tempi che

interessano il fenomeno. Il fine dell’analisi dovrebbe essere quello di prevenire condizioni

di funzionamento limite, che potrebbero compromettere l’affidabilità del sistema.

Nel corso di questo capitolo si presenta, allora, una breve trattazione riguardante le

principali vulnerabilità che possono compromettere la dependability di un sistema

operativo. Inoltre, vengono descritti alcuni studi sul software aging in ambienti

UNIX/Linux, in maniera tale da definire lo stato dell’arte nell’analisi del fenomeno ed una

base solida su cui fondare la procedura presentata nel seguito della tesi.

Page 47: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

40

2.1 Sistemi operativi e dependability

Un SO, come definito in [2], consiste in un insieme di programmi (software) che

gestisce gli elementi fisici (hardware) di un sistema di calcolo. Esso è composto

principalmente da un set di subroutine e strutture dati per il controllo e la gestione:

- dei componenti hardware costituenti un calcolatore;

- dei programmi che su di esso vengono eseguiti.

Molti sistemi operativi sono utilizzati in scenari life critical in cui è necessario

salvaguardare la sicurezza e l’incolumità di enormi masse di persone (basti pensare ai

sistemi radar che governano il traffico aereo). Altri sono alla base di sistemi commerciali e

bancari nei quali è inaccettabile il minimo errore o l’indisponibilità del servizio anche per

periodi brevi. Ne deriva che assicurare l’affidabilità di siffatti sistemi è una questione di

indiscutibile interesse.

I moderni SO hanno due caratteristiche che li rendono fortemente vulnerabili:

- contengono un’enorme quantità di codice;

- hanno uno scarso isolamento rispetto ai guasti.

Per quel che riguarda il primo punto, si stima che il kernel di Linux contenga più di 10

milioni di linee di codice, mentre quello di Windows XP ne abbia circa 23 milioni.

Ovviamente tali dimensioni implicano, per loro stessa natura, l’esistenza di una serie di

bug non rilevati nelle fasi di debugging e testing. A tal proposito, sono stati effettuati molti

studi statistici con lo scopo di stimare la quantità di errori presente nei software di grande

complessità. Ad esempio, in [16] si calcola che i SO possono contenere fra i 6 ed i 16 bug

per 1000 linee di codice eseguibile, mentre in [17] si afferma che la densità varia dai 2 ai

75 bug per 1000 linee di codice, in funzione dalla dimensione del modulo in esame. Stando

al primo approccio, il kernel di Linux potrebbe dunque contenere un insieme di bug

dell’ordine di 75.000 unità. Del resto, la presenza di una mole di errori così consistente è

stata illustrata già nel 2001 nello studio presentato in [18], che ha il fine di analizzare la

localizzazione e la distribuzione dei bug nei vari moduli del kernel Linux. Tale analisi,

basata sulla ricerca automatica degli errori tramite estensioni del compilatore, mostra che il

Page 48: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

41

codice relativo ai driver, il quale rappresenta circa il 70% dell’intero SO, è il più ricco di

bug, sia in termini di numero assoluto di errori (il che si spiega facilmente considerando la

mole di questa tipologia di codice) che per quel che riguarda il rate medio di bug. Tale

caratteristica va spiegata considerando due fattori. Innanzitutto, bisogna tener presente che

i driver di Linux vengono sviluppati da un gran numero di programmatori diversi che

hanno più familiarità con le periferiche che con il sistema operativo e che, quindi,

commettono facilmente errori nell’utilizzare le interfacce messe a disposizione da

quest’ultimo. In secondo luogo, spesso i driver non sono testati a fondo come altre porzioni

del kernel, anche a causa della grande varietà di dispositivi periferici e delle loro

configurazioni.

Indipendentemente dalla precisione delle stime che si trovano in letteratura, quel che è

certo è che la complessità dei SO fa sì che trovare e correggere tutti i bug in fase di

progetto, sviluppo e testing è chiaramente impossibile. Infatti:

- i tempi di individuazione di un solo bug sono generalmente molto lunghi e, di

conseguenza, volendo ipoteticamente rimuovere tutti gli errori dal codice (cosa

praticamente infattibile), tale tempo andrebbe moltiplicato per il numero totale di bug

del sistema;

- il tentativo di riparazione di un bug può ingenerarne di nuovi.

L’analisi di un SO deve anche tener presente che questo tipo di sistemi software,

tipicamente, non vengono sviluppati da zero ma migliorati semplicemente rispetto a

versioni precedenti e resi disponibili per l’utilizzo in un breve lasso di tempo (ciò accade

anche per il sistema operativo Linux). Si parla, in tal caso, di sistemi OTS (Off-The-Shelf) i

quali, in generale, vengono sviluppati per andare incontro alle esigenze di molteplici utenti,

bilanciando costi, tempi e prestazioni. Un siffatto approccio rende elevata la probabilità

che gli utenti, utilizzando il software, causino comportamenti non previsti dagli

sviluppatori (e quindi anche guasti). Tale fenomeno è noto come dependability pitfall: a

fronte di una sostanziosa riduzione dei tempi di sviluppo, della quantità di codice da

scrivere, nonché dei costi, aumenta la probabilità di effetti difficilmente riproducibili,

Page 49: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

42

dovuti principalmente all’integrazione dei vari componenti. Tipicamente, le attività di

testing permettono di individuare solo i guasti permanenti (che si manifestano quando

l’applicazione esibisce comportamenti non conformi alle specifiche di progetto), lasciando

insoluti quelli transienti, che sono il risultato di particolari e temporanee condizioni

ambientali, non prevedibili a priori e spesso difficili da riprodurre.

Oltre alla dimensione, una seconda vulnerabilità dei SO è rappresentata, come si è detto,

dallo scarso isolamento rispetto ai guasti. Un sistema software è costituito da componenti

isolate quando i moduli che ne fanno parte risultano ben incapsulati e comunicano fra loro

solo attraverso specifiche interfacce. La peculiarità delle catene di errori nei sistemi

operativi è rappresentata dal fatto che un guasto non rimane circoscritto alle aree in cui si

presenta ma, il più delle volte, si estende in maniera casuale alle varie componenti della

macchina, con possibilità di crash dell’intero sistema. I singoli moduli software costituenti

il SO non sono, infatti, isolati bensì interconnessi in modo complesso, per cui un

malfunzionamento al loro interno implica spesso comportamenti ed effetti casuali e non

facilmente tracciabili. Ovviamente, la rimozione dei bug, una volta individuati, risulterebbe

notevolmente semplificata se i vari componenti del sistema operativo fossero isolati in

maniera opportuna. In tal modo, sarebbe anche più semplice modificare un singolo

sottosistema, evitare la propagazione di un fault in parte o in tutto il resto del SO e far sì

che la rimozione di un bug non ne provochi altri. Tuttavia è difficile, se non impossibile,

assicurare l’isolamento dei moduli del kernel, non solo a causa della loro complessità ma

anche perché, come si è detto, se ne producono continuamente versioni aggiornate, di

norma aggiungendo o modificando codice esistente.

Concludendo, non si può evitare che un SO abbia dei bug (tantomeno degli aging-

related bug) e la rilevazione di questi è in ogni caso complessa. Si deve tener presente,

infatti, che più un sistema è articolato meno esso risulta tracciabile (diventa cioè sempre

più difficile monitorare lo stato delle sue risorse). Si può pensare, tuttavia, di applicare un

metodo che miri ad osservare lo stato del sistema operativo relativamente alle risorse

“consumate”. In tal modo, infatti, l’analisi degli errori potrebbe essere guidata

Page 50: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

43

dall’individuazione del componente (o dei componenti) che provoca l’esaurimento più o

meno graduale delle risorse computazionali, causando fallimenti (evidenti all’utente) o

ingenerando aging (latente, fino al momento del crash).

2.2 Studi correlati

Uno dei pochi studi condotti sul fenomeno del software aging nei SO è quello descritto

in [14], che fa uso del Simple Network Management Protocol (SNMP). Sulla base di tale

protocollo, gli autori definiscono un tool di monitoring distribuito, impiegato per

collezionare, ad intervalli di tempo regolari, i dati relativi alle risorse utilizzate da

workstation UNIX connesse in rete. Per la rilevazione di eventuali trend di aging, tali

informazioni sono poi sottoposte ad operazioni statistiche e, al fine di quantificare gli

effetti dell’invecchiamento sul SO, viene utilizzata la metrica del TTE.

SNMP, come definito nella RFC 1157 [21], è un protocollo a livello applicativo in grado di

offrire servizi di network management nella suite IP. Esso si basa su tre componenti

principali: il manager, l’agent ed il MIB (Management Information Based). La relazione

client-server tra manager ed agent è definita da SNMP, mentre il MIB descrive le

informazioni che possono essere ottenute o modificate attraverso interazioni tra le entità

precedentemente menzionate.

Il framework SNMP è stato utilizzato per progettare ed implementare un tool di

tracciamento delle risorse distribuito, con l’obiettivo di monitorare da remoto la vita di 3

workstation UNIX, connesse sulla stessa Ethernet LAN in un laboratorio della Duke

University. I 3 moduli chiave del tool sono:

- Pro-active Fault Management MIB (PFM MIB), che definisce gli oggetti utilizzati

per determinare lo stato di salute delle workstation;

- PFM agent, che rappresenta il processo agent eseguito in background su ogni

macchina monitorata;

Page 51: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

44

- PFM manager, la cui funzione primaria consiste nel recuperare i valori degli oggetti

desiderati, attraverso l’invio di richieste get agli agent dislocati nella rete.

In figura 2.1 è mostrato l’albero MIB per il modulo PMF. Poiché gli oggetti per MIB

proprietari vanno definiti in un sottoalbero posizionato sotto il ramo enterprises, il

modulo pfmMIB è stato definito nella gerarchia come {enterprises 2598} (dove il

valore 2598 è arbitrario).

Figura 2.1: albero MIB per il modulo PFM del tool di monitoring SNMP.

Gli oggetti monitorati sono classificati nelle 7 seguenti categorie, rappresentante ciascuna

un oggetto simbolico all’interno del modulo:

- hostID (definito come {pfmMIB 1}), i cui oggetti foglia, nodeName, osName,

osRelease, osVersion e mcHardwareName, definiscono le caratteristiche delle

workstation;

Page 52: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

45

- timeVal (definito come {pfmMIB 7}), che contiene due oggetti foglia,

dataAndTime e hostUpStats, rappresentanti rispettivamente la data e l’ora

corrente e l’istante dell’ultimo reboot della macchina;

- osResource (definito come {pfmMIB 2}), i cui oggetti foglia descrivono lo stato

delle risorse del sistema operativo. Alcuni di questi sono usedSwapSpace,

fileTableSize, realMemoryFree e procsTotal;

- procStats (definito come {pfmMIB 4}), con oggetti foglia che descrivono lo stato

dei processi running all’interno macchina;

- fileSysResource (definito come {pfmMIB 5}), i cui oggetti foglia,

tmpDirSize, tmpDirUsed, tmpDirAvail e tmpDirCapacity, tengono traccia

della directory /tmp dei sistemi UNIX like;

- netResource (definito come {pfmMIB 3}), che viene utilizzato per monitorare la

disponibilità e l’utilizzo delle risorse relative al sottosistema di networking;

- ioResource (definito come {pfmMIB 6}), che contiene informazioni inerenti alle

operazioni effettuate, attraverso i terminali, sull’ I/O da/verso il disco.

Figura 2.2: monitoring delle informazioni UNIX tramite SNMP.

Una singola istanza per ogni oggetto foglia del MIB è inizializzata come una variabile

globale nel programma agent, il quale ascolta passivamente su un numero di porto

prefissato. Nel caso venga ricevuta una richiesta di get dal manager, l’agent esegue un

Page 53: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

46

insieme di istruzioni per ottenere il valore degli oggetti foglia richiesti dal SO, assegna il

valore alla variabile ed invia la risposta al manager. In particolare, i valori degli oggetti

foglia sono ottenuti dall’agent eseguendo un insieme di utility UNIX messe a disposizioni

dal sistema operativo come pstat, iostat, vmstat, nfsstat, top e df. Tale procedura

è schematizzata in figura 2.2.

I valori relativi a tutti gli oggetti sono stati reperiti ogni 15 minuti ed i dati memorizzati in

file aventi formattazione del tipo nome-valore, riportanti il nome dell’oggetto

monitorato ed il suo valore, istante per istante. Le informazioni collezionate sono state

allora osservate in funzione del tempo, al fine di:

- verificare l’esistenza di trend di aging;

- definire la natura delle variazioni;

- quantificare l’aging nel SO UNIX.

La verifica della presenza di un trend sull’utilizzo delle risorse nel sistema operativo è stata

condotta tramite il test di Mann-Kendall (cfr. Capitolo 4). Una volta confermata la

presenza del trend, la sua pendenza è stata calcolata con il metodo dei minimi quadrati

implementato attraverso i test di regressione lineare. È stato allora possibile definire il TTE

relativo alle seguenti risorse:

- memoria reale libera;

- dimensione della tabella dei file;

- dimensione della tabella dei processi;

- spazio di swap utilizzato.

In particolare, detto m il coefficiente angolare stimato del trend e c l’intercetta del punto

iniziale, attraverso l’espressione

y=mx+c,

è possibile individuare dopo quanti giorni le risorse monitorate saranno completamente

esaurite (determinando il valore di x per cui y=0).

In base alla classificazione delle tecniche di analisi dell’aging presentata nel paragrafo 1.5,

lo studio appena esposto si può definire come basato su misure ed indipendente dal

Page 54: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

47

workload. Esso, infatti, colleziona un insieme di informazioni di sistema al fine di

individuare un trend di aging, senza tuttavia tener conto del carico di lavoro imposto alle

workstation.

Un approccio basato sul workload si trova, invece, nella trattazione esposta in [15], che

riprende ed approfondisce lo studio precedentemente descritto ma utilizza una metodologia

per l’analisi dell’aging ibrida, cioè basata sia su un modello analitico che su misure

statistiche. In particolare, la collezione dei dati di sistema è molto simile al caso

precedente: vengono infatti monitorate 9 workstation UNIX eterogenee, connesse ad una

stessa Ethernet LAN, raccogliendo più di 100 parametri ad intervalli regolari di 10 minuti.

Come accennato nel paragrafo 1.5.2, la caratterizzazione del workload è effettuata

attraverso un modello semi-Markoviano, che si fonda proprio sulla stima dell’uso delle

risorse monitorate tramite il tool SNMP. In particolar modo, fra tutte le variabili

controllate, si è scelto di basare l’analisi solo sulle seguenti:

- numero di context switch effettuati in un intervallo di tempo;

- numero di system call invocate in un periodo di tempo predefinito;

- pageIn;

- pageOut.

Tali informazioni definiscono, nello spazio a quattro dimensioni, il workload misurato in

un dato intervallo di tempo. Per individuare una serie di stati differenti di workload

(ciascuno dei quali rappresenti una situazione di carico per il sistema ben definita), viene

utilizzata la cluster analysis. La catena semi-Markoviana, allora, può trovarsi in uno degli

stati determinati e commutare da uno stato i ad uno stato j attraverso un processo che può

essere considerato a due stadi. Nello stadio iniziale, la catena permane in i per un certo

periodo di tempo descritto da una distribuzione Hi(t), denominata sojourn time. Nel

secondo stadio, invece, essa si muove nello stadio j con probabilità pij. Dunque, per

caratterizzare il processo semi-Markoviano (cioè il workload) è necessario definire la

matrice P delle probabilità di transizione da uno stato all’altro ed il vettore H(t) che

descrive la distribuzione statistica del tempo speso dal sistema in ogni stato. Dopo queste

Page 55: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

48

stime, per ciascuna risorsa monitorata e per ogni stato della catena, viene definita una

funzione di costo, detta reward rate rij, che rappresenta la variazione del consumo della

risorsa i nello stato j. Il modello così costituito è stato risolto con un tool automatico allo

scopo di stimare il TTE relativo a ciascuna risorsa monitorata. I risultati del modello semi-

Markoviano vengono infine inseriti in un secondo modello ad alta affidabilità, che tiene

conto sia dei fallimenti seguiti da azioni di ripristino che delle attività di recovery

proattive. Tale modello esaustivo viene utilizzato per derivare lo scheduling ottimo di

rejuvenation che massimizza la disponibilità del sistema o minimizza il costo dovuto ai

fallimenti.

Come si evince, l’approccio descritto è notevolmente più complesso del primo, poiché si

basa su strumenti matematici molto laboriosi (le catene semi-Markoviane, il reward rate, il

modello esaustivo per lo scheduling ottimo di rejuvenation, ecc.).

Un ulteriore interessante studio sul software aging è presentato in [33] e si concentra

sull’analisi dell’utilizzo delle risorse in un web server Apache. In particolare, i dati

vengono collezionati ponendo il sistema in condizioni di sovraccarico tramite Httperf,

un tool per misurazione delle performance di un web server, basato sull’invio periodico di

richieste http. Gli esperimenti hanno mostrato l’esistenza di software aging. Sono state così

applicate sia una tecnica statistica non parametrica che una parametrica basata su serie

temporali per l’analisi del fenomeno e la stima dello scheduling ottimale di rejuvenation. A

valle di tali analisi, effettuando operazioni di kill sui processi Apache (ad intervalli

fissati dalle precedenti stime), è stato osservato un offset nel trend di aging, senza tuttavia

che questo fosse eliminato. Questo “aging residuo” è stato dunque attribuito all’attività del

sistema operativo.

Gli studi descritti presentano alcuni punti di debolezza. Innanzitutto, essi si propongono

di analizzare l’aging dei sistemi UNIX/Linux con appositi tool di monitoring, senza

tuttavia spiegare in maniera chiara come va tenuta in conto l’azione dello strumento nelle

misure effettuate. Risulta infatti ovvio che l’interposizione di un protocollo di rete fra la

macchina da analizzare e la misura collezionata, aggiunge un certo overhead (in tempo e

Page 56: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

49

memoria occupata) al sistema nel suo complesso. Inoltre, nei primi due casi,

l’invecchiamento viene analizzato per un insieme di workstation connesse in rete e,

dunque, si forza il comportamento di ciascuna macchina ad una condizione di

funzionamento che non può essere ritenuta del tutto generale. In altre parole, questi lavori

considerano l’aging complessivo dell’apparato costituito da sistema operativo più

applicazioni.

Per contro, la procedura proposta nei prossimi capitoli si concentra sul software aging

introdotto esclusivamente dal kernel e, a tal fine, fa uso di carichi sintetici all’interno di un

ambiente controllato. Quantificare l’aging del solo SO può allora servire ad isolare il

contributo di quest’ultimo da quello della particolare applicazione in esecuzione. Il

procedimento sperimentale descritto si basa, comunque, su alcuni concetti utilizzati nei due

studi appena illustrati (come la normalizzazione dei dati raccolti, l’utilizzo del process file

system, ecc.) ma propone, come si vedrà, un approccio più semplice per il tracing delle

informazioni di sistema di un singolo kernel Linux. Tale procedura non si affida a

componenti o protocolli esterni al sistema da monitorare ma a sonde posizionate all’interno

del SO.

Page 57: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

50

Capitolo 3 Instrumentazione del sistema operativo Linux

Nel corso di questo capitolo si presenta inizialmente una breve descrizione del SO

Linux, per poi entrare nello specifico del kernel e della relativa instrumentazione di codice.

Lo scopo della digressione introduttiva sulla struttura del SO consiste nel mostrare

l’estrema complessità dell’architettura software in esame che si traduce in una pari

difficoltà d’analisi. Inoltre, la descrizione dei sottosistemi del kernel aiuta ad individuare

l’insieme delle aree di interesse da monitorare, al fine di controllare lo stato delle risorse.

Viene così descritto un meccanismo che può essere utilizzato per il tracing delle

informazioni di sistema, su cui si basa la procedura proposta per lo studio del fenomeno di

software aging.

3.1 Struttura del sistema operativo Linux

Il sistema operativo Linux è costituito da tre parti principali di codice (come accade per

la maggioranza delle implementazioni tradizionali di UNIX) [2]:

- il kernel, che è responsabile della gestione di tutte le principali astrazioni del sistema

operativo (tra le quali la memoria virtuale ed i processi) e consente un accesso

protetto e supervisionato alle risorse hardware;

- le librerie di sistema, che definiscono un set di funzioni standard (tramite le quali le

applicazioni possono interagire con il kernel) e realizzano la maggior parte dei

Page 58: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

51

servizi del SO che non necessitano dei pieni privilegi del nucleo. Esse implementano

molte funzionalità, come l’accesso ai file e l’allocazione della memoria;

- le utilità di sistema, cioè programmi che eseguono funzioni di gestione singole e

specializzate. Alcune di queste utility vengono richiamate solo una volta, al fine di

inizializzare o configurare peculiari aspetti del sistema; altre, che nella terminologia

UNIX vengono chiamate demoni, sono in esecuzione in modo permanente, con il

compito di gestire servizi continui, come la risposta alle connessioni di rete in

ingresso, l’accettazione delle richieste di login dai terminali oppure l’aggiornamento

dei file di log.

A differenza della maggioranza dei kernel UNIX, Linux non è monolitico ed offre un

ottimo supporto alla modularità [20]. È cioè possibile caricare o escludere dinamicamente

porzioni del kernel (tipicamente quelle relative ai driver dei dispositivi), che sono appunto

chiamate moduli. I principali vantaggi nell’utilizzo dei moduli sono i seguenti:

- quando viene scritto un nuovo driver, non è necessario ricompilare il nucleo

modificato, collegarlo e ricaricarlo nel sistema. Questa procedura onerosa, infatti,

viene eliminata grazie all’approccio modulare, che consente di compilare

separatamente il driver e caricarlo nel kernel già in uso;

- ciascun modulo non dipende dalla piattaforma hardware;

- un modulo può essere linkato al kernel in esecuzione quando sono necessarie le sue

funzionalità ed eliminato se non ce n’è più bisogno. Ciò rende ottimale l’uso della

memoria;

- una volta caricato, il nuovo modulo è equivalente al codice oggetto staticamente

linkato al kernel. Quindi, esso è eseguito in maniera privilegiata, con pieno accesso

alle risorse computazionali e non c’è dunque bisogno di passare nessun messaggio

particolare per invocare le sue funzioni. Ne deriva che l’utilizzo di un modulo linkato

dinamicamente non implica nessun degrado delle prestazioni rispetto all’uso del

codice statico.

Gli elementi principali della struttura a moduli di Linux sono [2]:

Page 59: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

52

- la gestione dei moduli, che consente il caricamento in memoria dei moduli aggiunti e

la loro comunicazione con il resto del nucleo;

- la registrazione dei moduli, la quale consiste nel comunicare alle altre componenti

l’esistenza di un nuovo modulo;

- la risoluzione dei conflitti, che permette ad un modulo di riservarsi l’uso di certe

risorse fisiche, proteggendole dall’interferenza accidentale di altri moduli.

La figura 3.1 esemplifica la struttura di Linux. Al livello più alto dell’architettura c’è lo

spazio utente (user space), in cui vengono eseguite le applicazioni. Al di sotto di tale strato

vi è il cosiddetto kernel space, contenente il cuore del sistema operativo. Il kernel può

essere suddiviso ulteriormente in tre sottolivelli:

- system call interface, per la gestione delle chiamate di sistema;

- codice del kernel indipendente dall’architettura della macchina;

- codice del kernel dipendente dall’architettura della macchina, il quale costituisce

quello che viene più comunemente denominato BSP (Board Support Package). Esso

varia a seconda del processore e della specifica piattaforma per una data architettura.

Figura 3.1: architettura fondamentale del SO Linux.

Page 60: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

53

Dell’user space fa parte anche la libreria GNU C (glibc) [19] che gestisce l’interfaccia

con le system call ed i meccanismi di transizione tra kernel e user space. Essa si basa sugli

standard ISO C e POSIX, nonché sulle implementazioni System V e Berkeley UNIX. La

libreria contiene facility per la gestione dei caratteri, delle stringhe e degli array, della

memoria virtuale e delle pagine, dei file e degli stream, dei socket, dell’interfaccia

terminale e dell’I/O a basso livello, dei processi, degli utenti e dei gruppi, come pure

funzioni matematiche e per la gestione dei segnali d’interruzione. Le operazioni principali

vengono implementate invocando le system call (in quanto alle applicazioni non è

concesso l’accesso diretto al tali chiamate). Una system call è un servizio che un

programma richiede al kernel poiché solo quest’ultimo possiede i privilegi per eseguirlo. I

programmatori non hanno bisogno di conoscere i dettagli delle chiamate di sistema perché

la libreria GNU C mette a disposizione funzioni che virtualmente offrono tutti i servizi

delle system call, fungendo da wrapper e gestendo il passaggio del controllo alle reali

chiamate di sistema. Ad esempio, per modificare i permessi assegnati ad un file, si utilizza

comunemente la chiamata di libreria chmod e non direttamente la system call che gestisce

il servizio in kernel space. Tuttavia, in problemi di programmazione molto specifici, può

essere necessario dover creare una chiamata di sistema esplicitamente e, a tale scopo,

glibc mette a disposizione la funzione syscall. Nella maggioranza dei casi, comunque,

il ricorso a tale funzione non è necessario e i servizi del kernel vengono invocati come

mostra, in maniera schematica, la figura 3.2 (che presenta un esempio relativo alla system

call read).

Figura 3.2: esempio di system call nel SO Linux.

Page 61: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

54

Il SO Linux mette a disposizione due possibili modalità di esecuzione [20]:

- user mode, per normali applicazioni e librerie d’utente, che non possono accedere

liberamente alle strutture dati ed ai programmi del kernel;

- kernel mode, per il codice appartenente al sistema operativo che viene eseguito in

modalità privilegiata del processore, con accesso totale a tutte le risorse fisiche del

computer. Tale modalità viene utilizzata per il codice del kernel (contenuto in un

eseguibile principale, denominato vmlinuz), per quello relativo alle chiamate di sistema

(le Interrupt Service Routine – ISR), per lo scheduler, per il gestore della memoria, e così

via.

Ogni CPU fornisce istruzioni speciali per commutare dall’user mode al kernel mode e

viceversa. Generalmente un programma viene eseguito in user mode e si passa all’altra

modalità solo quando esso richiede servizi al kernel il quale, dopo averli espletati, riporta il

processo in user mode. Relativamente all’esecuzione in modalità utente, un processo [2]

può essere definito come una entità del sistema operativo che esegue codice appartenete

alle applicazioni, alle quali è offerta l’astrazione di una macchina virtuale a loro esclusiva

disposizione. Tale macchina virtuale comprende un processore, una memoria contenente

codice eseguibile, stack, heap, metodi per invocare chiamate di sistema, ecc.. Quindi, un

processo [20] è un’entità virtuale che solitamente ha tempo di vita limitato all’interno del

sistema. I task di creazione, distruzione e sincronizzazione dei processi esistenti sono

demandati ad un gruppo di routine del kernel. In tal senso, il kernel stesso non va inteso

come un processo speciale bensì come un gestore di processi. Il modello user/kernel mode

assume che i processi richiedano servizi al SO tramite apposite system call in grado di

eseguire, per prima cosa, le istruzioni (dipendenti dall’hardware) per commutare dall’user

al kernel mode.

In un sistema monoprocessore, solo un processo alla volta può essere in esecuzione e

passare da una modalità all’altra come, ad esempio, illustra la figura 3.3. In essa il processo

1 è in user mode e passa al kernel mode dopo aver richiesto un servizio del SO tramite

system call (o meglio tramite un apposito wrapper della libreria GNU C). Dopo

Page 62: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

55

l’espletamento del servizio, il processo torna in modalità utente finché non occorre una

timer interrupt (la quale indica che il tempo a disposizione del processo 1 è finito). Di

conseguenza, viene attivato lo scheduler in modalità supervisore che sceglie di eseguire un

nuovo processo. Ha così luogo un context switch che porta il processo 2 ad essere eseguito

in user mode, sino ad un’interruzione che richiede l’uso di un dispositivo hardware. Il

kernel serve allora l’interruzione in modalità privilegiata, dopodiché commuta di nuovo in

modalità utente per continuare l’esecuzione del processo 2.

Figura 3.3: transizione tra user e kernel mode per l’esecuzione di due processi.

Quest’esempio mostra che le routine del kernel possono essere attivate in vari modi:

- tramite l’invocazione di una system call da parte di un processo (quindi in maniera

sincrona);

- quando un processo in esecuzione solleva un’eccezione, ossia una condizione

inusuale dovuta, ad esempio, ad una istruzione non valida;

- quando un dispositivo periferico alza un segnale di interruzione per notificare alla

CPU l’occorrenza di un evento (come, ad esempio, la fine di un’operazione di I/O).

Ciascuna interruzione viene servita, in tal caso, da un programma del kernel detto

interrupt handler e può presentarsi in qualunque istante poiché le periferiche operano

in maniera asincrona rispetto al processore;

- se viene eseguito un cosiddetto kernel thread, cioè un particolare processo

privilegiato che gira in kernel mode e nello spazio di indirizzamento del kernel e che

Page 63: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

56

non interagisce con gli utenti né richiede l’uso di dispositivi periferici (tali thread

sono creati, di solito, all’avvio del sistema e restano attivi fino allo spegnimento).

Per quanto riguarda la gestione della memoria, un processo utente è costretto a rimanere

entro il suo spazio di indirizzamento (memoria virtuale) in maniera tale da non poter

accedere direttamente a dati o istruzioni di altri processi e del sistema operativo né agli

indirizzi dei dispositivi. In tal modo, il SO rende le risorse di sistema protette facendo sì

che un processo sia in grado di colloquiare con l’esterno soltanto attraverso di esso, tramite

chiamate di sistema (per risorse private) o file memory mapped e shared memory (per

risorse condivise). Una piccola porzione dello spazio di indirizzamento di ogni processo è

riservata ai dati del kernel. In particolare, i primi 3 GB sono disponibili per il processo

mentre l’ultimo GB è riservato al kernel e buona parte di questo è mappato direttamente

con la memoria fisica. La tabella delle pagine relativa a quest’ultima parte di memoria,

definita master kernel page table, è identica per tutti i processi. Il kernel può accedere alle

pagine di tutti i processi, spostarle, swapparle ed utilizzare parte della memoria fisica per le

strutture dati e per l’I/O.

Figura 3.4: accesso alla memoria nella commutazione tra user e kernel mode.

Page 64: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

57

Quando viene invocata una chiamata di sistema, non è dunque necessario un cambio di

contesto totale in quanto il codice del kernel può accedere all’ultimo GB dello spazio di

indirizzamento del processo (in esecuzione in user mode) e commutare, quindi, in kernel

mode. La figura 3.4 esemplifica il passaggio fra le due modalità di esecuzione.

3.1.1 Sottosistemi del kernel

Il kernel Linux può essere visto come un aggregato di sottosistemi tra loro comunicanti,

ciascuno dei quali offre peculiari funzionalità. In particolare, possono essere identificati 5

sottosistemi (figura 3.5), adeguatamente descritti in [2]:

- process management;

- memory management;

- file system;

- networking;

- device control.

Figura 3.5: sottosistemi del kernel Linux.

Page 65: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

58

3.1.1.1 Process management

Al primo sottosistema menzionato è demandata la gestione di ciascun processo, definito

come il contesto di base all’interno del quale ogni attività richiesta da un utente viene

elaborata dal SO. Linux adotta un modello dei processi simile a quello di UNIX per

mantenere una certa compatibilità, pur discostandosi da quest’ultimo per alcuni aspetti. In

particolare, come UNIX, la gestione dei processi è espletata secondo il modello fork-exec:

un nuovo processo viene creato con la chiamata di sistema fork, mentre un nuovo

programma viene eseguito tramite una execve. Le due funzioni sono nettamente

differenti, nel senso che si può creare un processo con la fork senza necessariamente

avviare un nuovo programma e, similmente, l’esecuzione di un nuovo programma non

richiede la creazione preventiva di un processo. Il vantaggio di tale approccio risiede nella

sua estrema semplicità. Piuttosto che dover specificare ogni dettaglio sull’ambiente

relativo ad un nuovo programma, questo viene semplicemente eseguito nell’ambiente

esistente. Se poi un processo padre desidera modificare l’ambiente nel quale dovrà essere

eseguito un processo figlio, può richiamare una fork ed altre system call per modificare il

processo figlio prima di lanciarne l’effettiva esecuzione. Da questo approccio deriva che,

in UNIX, un processo racchiude in sé tutte le informazioni necessarie al SO per gestire il

contesto di una sua singola esecuzione. In Linux, tale contesto può essere suddiviso in

alcune sezioni specifiche che contengono informazioni riguardanti:

- l’identità del processo, la quale consiste principalmente di un identificatore (process

identifier – PID), di eventuali altri identificatori che collegano il processo ad un

gruppo o ad una sessione di lavoro e di credenziali che specificano i diritti di accesso

del processo alle risorse del sistema;

- l’ambiente del processo, che questo eredita dal suo genitore. Esso è composto da un

vettore di argomenti (cioè l’elenco degli argomenti passati dalla riga di comando per

invocare l’esecuzione del programma) e da un vettore d’ambiente (ossia un elenco di

coppie del tipo NOME = VALORE che associano valori arbitrari alle variabili

d’ambiente);

Page 66: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

59

- il contesto del processo, che indica lo stato del programma in ogni istante.

Il kernel Linux prevede anche la gestione dei thread in maniera molto semplice, cioè

adottando una stessa rappresentazione interna per processi e thread. A differenza di un

processo, però, un thread viene creato mediante la system call clone, la quale definisce

una nuova identità per il nuovo processo ma permette a quest’ultimo di condividere lo

spazio di indirizzi con il genitore (a differenza della fork che crea, per il figlio, un

contesto del tutto nuovo).

Per quel che riguarda lo scheduling dei processi, Linux adotta due differenti algoritmi: uno

per l’equa suddivisione del tempo di CPU tra i vari processi e l’altro, basato sulla priorità

assoluta di questi, per le elaborazioni in tempo reale. Il primo usa un sistema a priorità

basato su crediti. Ogni processo possiede, cioè, un certo numero di crediti e, di volta in

volta, viene scelto per l’esecuzione quello con il massimo numero di crediti. Lo scheduling

in tempo reale, invece, può essere sia di tipo First-Come First-Served (FCFS) che Round-

Robin (RR). In entrambi i casi, lo scheduler sceglie il processo a priorità maggiore ma

nell’approccio FCFS il processo prescelto continua l’elaborazione fino alla terminazione o

fino a che esso stesso non si blocca, mentre nel caso RR esso può essere sospeso allo

scadere di un timeout.

3.1.1.2 Memory management

Il sottosistema di memory management consta di due componenti distinte: la prima si

occupa dell’allocazione e della deallocazione della memoria fisica; la seconda, invece,

della memoria virtuale.

Lo strumento principale per la gestione della memoria fisica è l’assegnatore delle pagine

che alloca lo spazio fisico seguendo un algoritmo buddy-heap. Secondo tale approccio,

ogni porzione di memoria assegnabile ha una compagna adiacente (buddy) e, quando

entrambe si liberano, esse vengono combinate per creare una regione più ampia la quale

avrà, a sua volta., una compagna contigua e così di seguito. Se la richiesta di una porzione

Page 67: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

60

piccola di memoria non può essere soddisfatta, allora una regione più ampia viene

suddivisa in due porzioni buddy e così via.

Molti componenti del SO Linux hanno la necessità di allocare intere pagine all’occorrenza

ma possono essere richiesti anche blocchi di memoria molto piccoli. Il kernel mette allora

a disposizione un allocatore addizionale, per la richiesta di porzioni di memoria aventi

dimensioni arbitrarie e non note a priori. Questo servizio, kmalloc (analogo alla funzione

malloc del linguaggio C) alloca intere pagine e, successivamente, le divide in porzioni più

piccole.

Il sistema di memoria virtuale gestisce, invece, il contenuto dello spazio di indirizzi

virtuale di ciascun processo. Come visto nel paragrafo precedente, il kernel riserva, per il

proprio uso interno, una regione (costante e dipendente dall’architettura) di spazio di

indirizzi virtuali per ogni processo. Le voci nella tabella delle pagine che mappano queste

pagine del kernel sono marcate come protette, cosicché le pagine stesse non siano visibili o

modificabili quando il processo è in esecuzione in modalità utente.

3.1.1.3 File system e device control

Per quel che riguarda la gestione del file system, Linux adotta lo stesso modello di

UNIX, secondo cui un file non è necessariamente un insieme di dati memorizzati in un

disco bensì qualsiasi elemento capace di implementare la lettura e la scrittura di un flusso

di informazioni.

Il kernel di Linux gestisce allora tutti i tipi di file, nascondendone i dettagli sulla struttura

interna, tramite uno strato software che costituisce il Virtual File System (VFS). Esso è

progettato secondo principi object oriented ed è composto da due componenti: un set di

definizioni che specificano le caratteristiche di un oggetto file ed un insieme di funzioni

che consentono di manipolare questi oggetti.

I tre tipi di oggetto principali definiti dal VFS sono l’oggetto inode e l’oggetto file, che

rappresentano file individuali, e l’oggetto file system, che rappresenta, appunto, un intero

Page 68: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

61

file system. In particolare, il primo descrive il file nel suo complesso, mentre il secondo

rappresenta un punto di accesso ai dati all’interno del file. L’oggetto file tiene cioè traccia

della posizione in cui il processo sta leggendo o scrivendo attualmente. L’oggetto file

system rappresenta, invece, un insieme connesso di file che costituiscono una gerarchia di

directory. Il kernel gestisce un unico oggetto file system per ciascun disco montato e per

ogni file system di rete accessibile. Quest’oggetto permette di accedere ai singoli inode

poiché il VFS identifica ognuno di essi tramite una coppia univoca <file system,

numero di inode> ed individua il particolare inode chiedendo all’oggetto file system

di riportargli quello con il numero in questione.

Per ognuno dei tre tipi di oggetti, il VFS definisce una serie di operazioni che devono

essere implementate dalla struttura dati. Ne deriva che ogni oggetto contiene un puntatore

ad una tabella di funzioni, la quale elenca gli indirizzi delle routine che espletano le

operazioni necessarie a manipolare l’oggetto. Il VFS non sa quindi se un inode rappresenta

un file di rete o uno memorizzato su un disco, una socket oppure una directory. La

funzione appropriata per l’operazione di lettura di quel file sarà comunque sempre nella

stessa posizione della tabella di funzioni e lo strato software del VFS chiamerà quella

funzione senza preoccuparsi di come i dati verranno realmente letti.

La visione appena descritta del file system rende relativamente semplici le funzionalità

del device control. Un utente può, infatti, aprire un canale di accesso ad una periferica

nello stesso modo in cui può accedere ad un qualunque altro file. Le periferiche appaiono,

cioè, come oggetti all’interno del file system.

Linux divide tutte le periferiche in tre classi:

- periferiche a blocchi (dischi, floppy, dischi ottici, ecc.), che permettono l’accesso a

blocchi di dati di dimensione fissa e completamente indipendenti;

- periferiche a caratteri, che comprendono la maggioranza degli altri dispositivi,

eccezion fatta per le periferiche di rete. I dispositivi a caratteri non devono

necessariamente fornire tutte le funzionalità connesse ai file ordinari. Ad esempio, un

dispositivo relativo ad un altoparlante consente la scrittura dei dati ma non la lettura;

Page 69: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

62

- periferiche di rete, che sono gestite diversamente rispetto alle classi precedenti

poiché gli utenti non possono trasferire dati direttamente da/verso queste ma devono

accedervi tramite il sottosistema di networking.

La distinzione tra dispositivi a blocchi ed a caratteri consiste nel tipo di accesso che nei

primi è casuale e nei secondi sequenziale. Inoltre, tipicamente i device a blocchi

leggono molti byte insieme, mentre quelli a caratteri uno o pochi byte alla volta.

3.1.1.4 Networking

Il sottosistema di rete di Linux risulta notevolmente progredito poiché, non solo

supporta i protocolli Internet standard utilizzati per la maggior parte delle comunicazioni

da UNIX a UNIX, ma implementa anche un numero di protocolli nativi di altri sistemi

operativi.

Internamente, le funzionalità di rete del kernel di Linux sono implementate da tre strati di

software:

- l’interfaccia socket;

- i driver dei protocolli;

- i driver delle periferiche di rete.

Le applicazioni utente eseguono tutte le richieste di rete attraverso l’interfaccia socket, in

modo che ogni programma progettato per fare uso delle socket di Berkley funzioni sotto

Linux senza nessun cambiamento del codice sorgente.

Lo strato successivo del software è lo stack dei protocolli. Ogni volta che arrivano dei dati

a questo strato, sia da una socket dell’applicazione che dal driver delle periferiche di rete,

ci si aspetta che essi siano marcati con un identificatore che specifichi con quale protocollo

devono essere trattati. Lo strato protocollo può riscrivere i pacchetti, crearne di nuovi,

dividere o riassemblare pacchetti in frammenti o, semplicemente, scartare dati in ingresso.

Una volta che ha terminato di processare un insieme di pacchetti, esso decide di inviarli

all’interfaccia socket (se i dati sono destinati a una connessione locale) oppure ai driver

Page 70: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

63

delle periferiche (se i pacchetti devono essere trasmessi verso un dispositivo remoto).

L’insieme dei protocolli supportati dal sistema di rete di Linux è costituito da TCP/IP,

UDP ed eventualmente anche altri come, ad esempio, ATM.

I servizi di rete sono offerti passando singole strutture dati dette skbuff. Esse contengono

un insieme di puntatori ad una porzione di memoria contigua, all’interno della quale è

possibile assemblare i pacchetti.

Nei prossimi paragrafi sarà descritto l’approccio measurement-based proposto per

collezionare informazioni, utili all’analisi dello stato di salute del kernel Linux. Come si

vedrà, sono stati previsti punti di monitoraggio in tutti i vari sottosistemi di cui si è appena

parlato.

3.1.2 Process file system

L’analisi di un SO implica il controllo di alcune informazioni di sistema, quali lo stato

delle periferiche hardware, della memoria, del processore, dei dischi e così via. Per

coadiuvare gli utenti nella raccolta di tali dati, Linux mette a disposizione il process file

system, noto semplicemente come file system proc [2]. In realtà /proc non è una vera e

propria directory ma un file system virtuale, che viene creato dinamicamente dal sistema e

non fa riferimento a nessun dispositivo fisico di memorizzazione. Ciò significa che i

contenuti di /proc non sono memorizzati in nessun luogo ma calcolati su richiesta. Anche

UNIX SVR4 adottava un file system di questo tipo in cui ciascuna directory corrispondeva

ad un processo attivo. Linux ha notevolmente ampliato l’idea originale, aggiungendo nuovi

file di testo contenenti le statistiche relative al kernel e ai driver caricati. Ad esempio, il

comando ps, che elenca lo stato dei processi in esecuzione, è implementato con un

programma ordinario che legge e compone in forma leggibile le informazioni contenute nel

in un file del proc.

Il process file system deve, per prima cosa, costruire la struttura di directory e i dati dei file

in essa contenuti. A tale scopo, esso deve definire in modo univoco un insieme di numeri

Page 71: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

64

di inode per ciascun file, che consentano al sistema di identificare la particolare operazione

richiesta dall’utente e di collocare le informazioni relative nella sezione di memoria di

lettura del processo richiedente. Poiché Linux utilizza PID a 16 bit ed il numero di inode è

invece lungo 32 bit, i primi 16 bit di quest’ultimo sono interpretati come un PID ed i

restanti identificano l’informazione richiesta. Un campo PID pari a zero indica che l’inode

contiene informazioni globali non relative ad uno specifico processo. Il process file system,

infatti, contiene molti file generali che forniscono informazioni sulla versione del nucleo,

sulle prestazioni, sulla memoria libera, ecc..

Il sottoalbero /proc/sys è accessibile tramite la system call sysctl che legge e scrive

i dati in formato binario (anziché in caratteri ASCII), in modo da evitare i ritardi introdotti

dal file system. Per visualizzare il contenuto di /proc è sufficiente digitare il comando ls

/proc che comporrà la lista delle sottodirectory denominate con valori numerici, contenti

informazioni relative ai processi che presentano quel dato PID, più un insieme di file

contenenti informazioni globali. Ad esempio, per ottenere informazioni sul processore,

basta accedere al contenuto del file cpuinfo, mentre per la memoria di sistema i dati di

interesse sono resi disponibili nel file meminfo.

Nel paragrafo 3.5 si illustra il modo in cui il process file system è stato utilizzato nella

procedura proposta, al fine di collezionare i campioni osservati sull’utilizzo della memoria.

3.2 Tracepoint nel kernel Linux

Dalla descrizione dei sottosistemi del kernel Linux, è possibile dedurre che le probabili

cause di aging possono riguardare un vasto insieme di informazioni presenti in ognuno dei

componenti. Al fine di analizzare il fenomeno, si può quindi implementare un’analisi

mesurement-based, tenendo traccia di un insieme di dati atto all’individuazione dei

sottosistemi ed eventualmente dei componenti del SO che influiscono maggiormente sul

trend di aging.

Page 72: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

65

A tal proposito, Linux mette a disposizione un supporto per il tracing delle informazioni di

sistema, costituito dai cosiddetti kernel tracepoint [22]. Tale componente, però, non

soddisfa a pieno le caratteristiche richieste per uno studio approfondito del fenomeno di

software aging. Per poter monitorare lo stato di ben definite variabili attraverso l’utilizzo di

tracepoint, si può comunque predisporre un nuovo tracer capace di acquisire

periodicamente tutti i dati di interesse.

I tracepoint possono essere definiti come degli hook lightweight, cioè dei ganci leggeri che

vanno posizionati in determinati punti nel codice del kernel per registrare l’occorrenza di

taluni eventi. Ciascun tracepoint definisce un’associata probe function per il reperimento

delle informazioni di interesse. Ogni volta che l’esecuzione passa per il tracepoint, la probe

function viene invocata e l’infrastruttura di tracing provvede a salvare il contesto

dell’evento e i dati desiderati all’interno di un tracing buffer. Il tracing buffer è poi

accessibile da user space montando il file system virtuale debugfs (di default su

/sys/kernel/debug) ed accedendo ai file /sys/kernel/debug/tracing/trace e

/sys/kernel/debug/tracing/trace_pipe. Da user space è possibile, inoltre,

attivare o disattivare il tracepoint tramite debugfs, scrivendo rispettivamente 1 o 0 nel file

/sys/kernel/debug/tracing/current_tracer con i comandi:

- echo 1 > tracing_enabled, per l’abilitazione;

- echo 0 > tracing_enabled, per la disattivazione del tracing.

Il modo più rapido per definire un tracepoint nel kernel Linux è quello di usare la event

tracing infrastructure, secondo cui il prototipo di un evento che caratterizza il tracepoint è

formato da:

- una definizione posizionata in un header file;

- uno statement (probe function), aggiunto al codice C del kernel per intercettare

l’evento.

La definizione di un tracepoint viene specificata con una macro del tipo:

Page 73: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

66

TRACE_EVENT(eventname,

TP_PROTO(int first_arg, const char *second_arg),

TP_ARGS(first_arg, second_arg),

TP_STRUCT__entry(

__field(int, num)

__string(str, second_arg)

),

TP_fast_assign(

__entry->num = first_arg;

__assign_str(str, second_arg);

),

TP_printk("%i %s", __entry->num, __get_str(str))

);

dove:

- eventname è un identificatore che indica il particolare evento da tracciare;

- la macro TP_PROTO() è usata per definire il prototipo della probe function invocata

dal tracepoint;

- la macro TP_ARGS() indica i nomi dei parametri dichiarati nel prototipo;

- la macro TP_fast_assign() contiene lo statement C che si occupa di assegnare la

entry ad ogni record del trace buffer (riferito con il nome __entry);

- la macro TP_printk() definisce il formato di ogni record tracciato (secondo lo stile

della printf()).

In questo esempio ogni entry nel trace buffer contiene un attributo numerico (num) ed uno

di tipo stringa (str). Il prototipo della probe function va definito come:

void trace_eventname(int first_arg, const char, *second_arg);

Page 74: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

67

in modo da poter posizionare la funzione in qualsiasi punto all’interno del codice del

kernel per intercettare l’evento eventname. Ogni volta che la probe function viene

invocata, il sistema di tracing provvede a registrare una nuova entry nel trace buffer.

Dopo aver realizzato il nuovo tracer, è poi possibile ricavare tutti i dati di interesse per

lo studio del software aging che riguarderanno, ovviamente, le aree critiche del sistema e,

quindi, i sottosistemi del kernel descritti in precedenza. In particolare, ci si propone di

tenere traccia:

- relativamente al sottosistema di file system, dell’evoluzione di un insieme ben

definito di system call (per quel che riguarda il numero di invocazioni di ognuna ed il

relativo tempo di esecuzione);

- di un set di informazioni relative al sottosistema di memory management, quali

numero totale di allocazioni e deallocazioni, numero di swap-in e swap-out e così

via;

- per quanto concerne il sottosistema di networking, del numero di socket aperte e

chiuse, sia per il protocollo TCP che per UDP;

- per il sottosistema di process management, del numero di context switch, del numero

di processi runnable, stopped, unrannable, ecc.;

- per quanto riguarda il sottosistema di I/O, del numero di interruzioni differenziate per

tipo, gestione di workqueue ecc.,

3.3 Individuazione delle informazioni di interesse

La procedura sperimentale proposta parte da una fase di design che punta alla

sistematizzazione degli scopi dell’analisi. Tale step include:

- la scelta dei sottosistemi da monitorare;

- l’identificazione delle informazioni da sottoporre a tracing per ciascun sottosistema

(informazioni di tracing o parametri di workload);

Page 75: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

68

- l’individuazione di alcuni dati di sistema da monitorare, attraverso i quali sia

possibile sintetizzare lo stato di salute del SO. Tali informazioni possono essere

definite come indicatori di aging.

Per quel che riguarda il primo punto, si è ritenuto opportuno condurre un’analisi quanto più

esaustiva possibile, collezionando dati da tutti i sottosistemi del kernel:

- process management;

- memory management;

- filesystem I/O;

- network I/O;

- driver control.

Per ciascun sottosistema va dunque definito un insieme di informazioni in grado di fornire

dati utili in caso si manifesti il fenomeno di aging durante un esperimento. Queste variabili

dovrebbero consentire di caratterizzare i parametri più significativi del workload, da poter

mettere in relazione con eventuali trend di aging.

Per individuare le informazioni di tracing è utile identificare, in primo luogo, in quali modi

può manifestarsi l’aging secondo il punto di vista dell’utente finale. In pratica, possono

essere individuati 3 indicatori di aging fondamentali:

- memory depletion, che può riguardare la riduzione della porzione di memoria fisica

libera disponibile, la diminuzione della quantità di spazio di swap libero disponibile

e, in generale, l’aumento del consumo totale di memoria;

- throughput loss, ossia la riduzione del numero di operazioni eseguite nell’unità di

tempo, che può manifestarsi a livello applicativo e di sistema operativo;

- time loss, per quel che concerne l’aumento del tempo medio di risposta a livello

applicativo e di SO

Nella procedura descritta l’analisi è stata finalizzata essenzialmente al monitoraggio della

memory depletion, per quanto riguarda la memoria libera disponibile, nonché al thruoghput

loss ed al time loss a livello di kernel.

Page 76: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

69

In base a tali scopi, è stato possibile allora individuare in maniera precisa le informazioni da

tracciare, che sono riportate nelle tabelle 3.1, 3.2 e 3.3 suddivise per sottosistema.

MEMORY MANAGEMENT PROCESS MANAGEMENT

Numero di flush su disco Numero di context switch

Numero di mmap() e munmap() Numero di task creati

Numero di brk() Numero di task distrutti

Numero di page miss Numero di task migrati tra CPU

Numero inserimenti e rimozioni page cache Numero di passaggi allo stato waiting

Numero di byte richiesti Numero di prelazioni

Numero di byte allocati Numero di task “stopped”

Numero di allocazioni Numero di task “unrunnable”

Numero di deallocazioni Numero di task “runnable”

Numero di allocazioni SLAB Numero di system call fork

Numero di deallocazioni SLAB Numero di system call clone

Numero di swap-in Numero di system call exec

Numero di swap-out

Tabella 3.1: informazioni di tracing per i sottosistemi di memory management e process management.

FILESYSTEM I/O NETWORK I/O

Numero di accesi in lettura su disco Numero di accessi a socket

Numero di accessi in scrittura su

disco Numero di socket aperte

Numero di file aperti Numero di socket chiuse

Numero di file chiusi Numero di accept, listen, bind e connect

Numero di access su file Numero di pacchetti TCP trasmessi

Numero di seek su file Numero di pacchetti TCP ricevuti

Numero di pacchetti UDP trasmessi

Tabella 3.2: informazioni di tracing per i sottosistemi di network I/O e file system I/O.

Page 77: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

70

DRIVER CONTROL

Numero di interrupt generati

Numero di tasklet e softirq servite

Numero inserimenti ed esecuzioni da workqueue

Numero workqueue create e distrutte

Tabella 3.3: informazioni di tracing per il sottosistema disk I/O driver.

Oltre ai dati appena riportati si è ritenuto necessario monitorare il tempo di latenza relativo

ad un gruppo critico di system call, così come descritto nel paragrafo 3.4.1.

3.4 Instrumentazione dei tracepoint e definizione del tracer

Una volta individuate le informazioni di tracing, è stato necessario identificare le

funzioni del kernel che le gestiscono ed inserire in ciascuna opportuni tracepoint. Come

visto nel paragrafo 3.2, un tracepoint può essere definito come un gancio all’interno del

codice del SO, cui è associata una determinata probe function, in grado di registrare

l’occorrenza di taluni eventi.

L’architettura event tracing messa a disposizione da Linux, in fase di design è apparsa però

un po’ troppo complessa, soprattutto in considerazione del gran numero di informazioni da

monitorare. Si è pensato, allora, di concepire i tracepoint come sonde definite da

piccolissime porzioni di codice (in particolare da opportune variabili globali di tipo

contatore e dalle operazioni di incremento su di esse), in grado di catturare lo stato

dell’informazione desiderata. Nel sistema così concepito, il valore di ciascun tracepoint

individua, quindi, il numero di un certo parametro, il cui incremento viene effettuato dalla

funzione in cui la sonda è stata instrumentata. Ad esempio, una volta determinata la

funzione all’interno del kernel che effettua il context switch tra processi, per poter tener

traccia del loro numero, è bastato inserire un semplice contatore all’interno della routine.

Tale contatore rappresenta allora il tracepoint per l’indicatore di context switch relativo al

sottosistema di process management. Sono state inoltre predisposte delle opportune

Page 78: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

71

funzioni di get() e set(), rispettivamente allo scopo di restituire ed azzerare lo stato di

ciascun tracepoint. Queste vengono invocate periodicamente dal tracer myTracer.c, al

fine di registrare lo stato corrente dei parametri di workload.

Tutti le informazioni relative ai vari sottosistemi sono state raggruppate all’interno di

un’apposita struttura dati, le cui istanze definiscono i cosiddetti trace event. Tale struttura è

locale al tracer e quest’ultimo, ad intervalli di tempo regolari (di 5 minuti) scanditi

attraverso un timer, provvede a:

- richiamare le funzioni get per reperire lo stato dei tracepoint;

- assegnare tali informazioni ai relativi campi della struttura dati;

- copiare l’intera struttura in un ring buffer, cioè una porzione di memoria, gestita

come una coda circolare, direttamente accessibile dal tracer;

- resettare lo stato dei tracepoint attraverso le funzioni di set.

Il SO provvede poi a rendere disponibile in user space il contenuto del ring buffer,

copiandolo nei file trace e trace_pipe del file system virtuale debugfs. La differenza

sostanziale tra trace e trace_pipe riguarda il fatto che il primo presenta una

formattazione direttamente interpretabile dall’utente ma non fornisce informazioni in

tempo reale, mentre il secondo è un file binario aggiornato ogniqualvolta viene recuperato

un nuovo evento di tracing. In particolare, trace_pipe non ritorna mai EOF (End Of

File), come accade comunemente per le pipe UNIX, in modo da permettere il

monitoraggio continuo di ulteriori dati, qualora appaiano. Ne deriva che, poiché

trace_pipe ha una struttura a pipe real-time, ciascun evento può essere recuperato una

sola volta, perché le informazioni vengono via via sovrascritte. Esso si configura, cioè,

come un file “consumer” in cui i dati , una volta letti (consumati), non sono più reperibili

attraverso una lettura successiva. Tuttavia, per la necessità di acquisizione degli eventi in

tempo reale, si è scelto di utilizzare le informazioni presenti nel file di output

trace_pipe. In particolare, un’apposita funzione definita in user-space, myTracer-

rep.c, recupera in real time gli eventi da tale file, estrae i dati in maniera opportuna, li

memorizza in archivi in formato testuale e li stampa a video.

Page 79: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

72

Page 80: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

73

Ciò permette di acquisire facilmente i dati contenuti negli eventi di tracing, i quali devono

poi essere sottoposti a valutazioni statistiche. Il funzionamento dell’intero sistema di

monitoring è esemplificato in figura 3.6.

Il tracer può essere utilizzato attraverso i seguenti passi:

- mount del file system debugfs attraverso il commando

mount -t debugfs none /debug;

- definizione dell’identificativo del tracer, attraverso il file current_tracer della

directory /debug/tracing tramite il comando

echo myTracer > current_tracer;

- abilitazione del tracing digitando

echo 1 > tracing_enabled.

A questo punto, per reperire le informazioni di tracing, scritte nel file di output

trace_pipe, va attivata la funzione in user space lanciando il comando

./myTracer-rep.

L’implementazione del tracer può essere considerata il contributo più rilevante di questo

lavoro di tesi. Infatti, la sua architettura costituisce un approccio originale al problema del

monitoring delle informazioni di stato delle risorse, le quali vengono reperite dall’interno

del sistema stesso, senza l’ausilio di protocolli o tool esterni. Il controllo di tali dati

avviene così in una maniera notevolmente semplice ed ha comportato la scrittura di una

minima porzione di codice.

L’approccio proposto assume un particolare interesse se si considera che esso può essere

utilizzato anche per studi differenti dall’analisi del software aging che coinvolgano,

comunque, il monitoraggio di qualsivoglia informazione reperibile all’interno del kernel.

Page 81: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

74

3.4.1 Rappresentazione dei dati relativi al tempo di latenza

Si è scelto di tener traccia della latenza di alcune operazioni in modo da stimare la

metrica del time loss utile al profiling del sistema. Per calcolare tale informazione è

necessario predisporre un’apposita coppia di tracepoint che inglobi il codice da monitorare.

Ad esempio, per stimare il tempo di latenza di una system call è necessario posizionare un

tracepoint all’inizio della funzione wrapper ed un altro alla fine della stessa, prima del

return.

Poiché differenti percorsi di esecuzione nel codice producono diversi picchi nella latenza, è

utile impiegare una rappresentazione esponenziale dei tempi, in quanto questi possono

subire variazioni anche diversi ordini di grandezza. Ad esempio, per restituire eventuali

informazioni in cache, il SO impiega un tempo non superiore a qualche nanosecondo;

mentre, per reperire gli stessi dati dall’hard disk o dalla rete, il tempo speso è dell’ordine

delle decine di millisecondi. Si può allora pensare di rappresentare i dati sotto forma di

vettori in cui la posizione i-esima corrisponde ad un intervallo temporale definito in scala

logaritmica e contiene il numero di system call servite in quel periodo. Se ad esempio la

latenza di una chiamata di sistema è pari a latency, allora sarà incrementato di una unità il

contenuto della posizione k-esima del vettore con k tale che:

2k-1 ≤ latency < 2k.

Dal vettore delle latenze finale è possibile determinare le seguenti informazioni:

- numero totale di invocazioni di system call con una data latenza;

- tempo medio di risposta di una determinata operazione;

- latenza totale per ogni intervallo di tempo.

In particolare, nella procedura sperimentale proposta è stato predisposto un vettore distinto

(incluso nella struttura dati del tracer) per monitorare il tempo di servizio di ciascuna delle

seguenti system call:

- open, che consente l’apertura di un file, attraverso il suo descrittore;

- close, che implementa la chiusura di un file, attraverso il suo descrittore;

- access, che controlla i permessi di un utente per un file;

Page 82: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

75

- lseek, che riposiziona l’offset di lettura e scrittura in un file;

- read, che esegue la lettura da una file;

- write, che effettua la scrittura in un file;

- mmap, utilizzato dai processi per creare un nuovo mapping di memoria;

- brk, che modifica la quantità di spazio allocato per una porzione di dati del processo

chiamante;

- munmap, utilizzato dai processi per eliminare o ridurre un mapping di memoria;

- fork, che crea un processo figlio;

- clone, che crea un thread;

- exec, che esegue un programma.

Anche le informazioni di latenza vengono salvate dalla funzione myTracer-rep.c, in

differenti file testuali.

Le figure 3.7 e 3.8 riportano, a titolo di esempio, gli istogrammi della latenza relativa alla

system call open, rispettivamente catturata in un determinato evento ed in una serie

successiva di eventi di un esperimento.

Figure 3.7: istogramma della latenza della system call open catturata in un unico evento.

La cattura del tempo di latenza è stata effettuata con l’ausilio della macro presentata di

seguito (adeguatamente semplificata rispetto a quella definita in [29]), attraverso cui è stato

Page 83: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

76

possibile reperire le informazioni in maniera semplice e con una minima aggiunta di

codice.

Figure 3.8: istogramma della latenza della system call open catturata in eventi successivi.

#ifndef _AGGREGATE_STATS_H_

#define _AGGREGATE_STATS_H_

#define RDTSC(qp) \

do { \

unsigned long lowPart, highPart; \

__asm__ __volatile__("rdtsc" : "=a" (lowPart), "=d" (highPart)); \

qp = (((unsigned long long) highPart) << 32) | lowPart; \

} while (0);

typedef uint32_t aggregate_stats[32];

#define AGGREGATE_STATS_PRE \

Page 84: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

77

unsigned long long l_aggregate_stats; \

RDTSC(l_aggregate_stats);

#define AGGREGATE_STATS_POST(stat) \

do { \

unsigned long long ll; \

unsigned int bucket, delay; \

RDTSC(ll); \

delay = (unsigned int)((ll - l_aggregate_stats) >> 5); \

for (bucket = 0; delay >> 1; bucket += 1) \

delay >>= 1; \

(stat)[bucket]++; \

} while(0);

#define AGGREGATE_STATS_INIT(stat) \

do { \

memset(stat, 0, 32 * sizeof(int)); \

} while (0);

#endif

La prima direttiva define, denominata RDTSC, è utilizzata per contare il numero di cicli

di clock del processore. In particolare, il kernel Linux, per eseguire il conteggio dei cicli di

clock, mette a disposizione un apposito registro contatore TSC (Time Stamp Counter), il cui

valore può essere letto attraverso la chiamata ad rdtsc [20]. Quando viene utilizzato il

registro, il kernel prende in considerazione la frequenza del segnale di clock e, di

conseguenza, decide ogni quanto tempo incrementare il time stamp. Se, ad esempio, la

frequenza di clock del processore è pari ad 1 GHz, il TSC è incrementato di una unità una

volta ogni nanosecondo. Grazie a tale meccanismo Linux è in grado fornire accurate

misurazioni temporali.

Attraverso la parola chiave typedef, è stato definito un nuovo tipo di dato denominato

aggregate_stats, che rappresenta un vettore di 32 elementi a 32 bit. Tale array

Page 85: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

78

contiene, a valle dell’operazione di calcolo, in ogni posizione i-esima il numero di system

call servite nell’intervallo di tempo compreso fra 2i-1 e 2i (con 375 ≤≤ i ) cicli di clock.

AGGREGATE_STATS_PRE, attraverso una opportuna chiamata ad RDTSC, avvia il conteggio

dei cicli di clock. AGGREGATE_STATS_POST permette di definire, a partire dal numero di

cicli di clock conteggiati, in quale degli intervalli ricade il tempo di latenza misurato e di

incrementare di conseguenza l’elemento corrispondente del vettore. Infine,

AGGREGATE_STATS_INIT, è utilizzato per allocare ed inizializzare a zero il vettore

relativo ad un determinato conteggio.

Per monitorare la latenza di una determinata system call, è stata definita all’interno del

codice del suo wrapper un vettore di tipo aggregate_stats e sono state richiamate le

direttive AGGREGATE_STATS_PRE e AGGREGATE_STATS_POST rispettivamente

all’ingresso e all’uscita della routine. In tal modo, è stata predisposta una coppia di punti di

monitoraggio del clock di sistema.

3.5 Scrittura delle informazioni di sistema su file: myTracer-rep

Al verificarsi di ogni nuovo evento di tracing, la funzione scritta in linguaggio C in user

space, myTracer-rep.c, effettua le seguenti operazioni:

- reperisce dal process file system i dati relativi all’indicatore di memory depletion;

- legge le informazioni scritte in trace_pipe tramite l’utilizzo del tracer e le

formatta opportunamente.

Per quel che riguarda il primo punto, la funzione user space legge dal file

/proc/meminfo contenente informazioni sulla memoria e reperisce in particolare la

quantità di memoria libera disponibile, scrivendone il valore nel file freeMem.txt. In

altre parole, il file formattato da myTracer-rep.c presenta, sotto forma di vettore

colonna, la quantità di memoria libera disponibile campionata periodicamente ogni 5

minuti, come avviene per il resto delle informazioni prelevate dal tracer.

Le informazioni lette da trace_pipe vengono invece distribuite fra i seguenti file:

Page 86: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

79

- mem.txt, contenente le informazioni relative al sottosistema di memory

management;

- proc.txt, che include i dati del sottosistema process management;

- disk.txt, che memorizza le informazioni relative al sottosistema disk I/O driver;

- net.txt, contenente i dati relativi al sottosistema di networking;

- filesystem.txt, che include le informazioni riguardanti il sottosistema di

filesystem I/O.

Nelle figure 3.9 si riportano gli schemi di formattazione dei file appena descritti:

Figura 3.9a: formattazione dei dati contenuti nel file mem.txt.

Figura 3.9b: formattazione dei dati contenuti nel file proc.txt.

Page 87: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

80

Figura 3.9c: formattazione dei dati contenuti nel file disk.txt.

Figura 3.9d: formattazione dei dati contenuti nel file net.txt.

Figura 3.9e: formattazione dei dati contenuti nel file filesys.txt.

Per quel che riguarda i tempi di latenza, myTracer-rep.c memorizza i vettori di tipo

aggregate_stats in file di testo denominati come le system call cui si riferiscono

(clone.txt, open.txt, close.txt, ecc.).

Page 88: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

81

Capitolo 4 Procedura sperimentale

In questo capitolo viene descritta la procedura sperimentale condotta per lo studio

dell’aging nel kernel Linux. L’approccio seguito è di tipo measurement-based e l’analisi

dei risultati si fonda sulla caratterizzazione preventiva del workload utilizzato per lo stress

del sistema.

Dopo aver introdotto i concetti generali inerenti alla progettazione degli esperimenti,

vengono definiti i passi della procedura prescelta, riguardanti l’identificazione,

l’acquisizione e l’elaborazione dei dati. La sperimentazione pone le sue basi nello studio

dei sottosistemi del kernel Linux, condotta nel capitolo precedente al fine di identificare le

potenziali vulnerabilità del SO nei confronti dell’aging. Lo scopo dell’analisi dei risultati

consiste nel comprendere quali sono i parametri più significativi del workload, da poter

mettere in relazione con eventuali trend di aging.

La procedura seguita consta fondamentalmente di due fasi:

- la raccolta delle informazioni sensibili, reperite tramite un apposito tracer

instrumentato in kernel-space e disponibili all’utente grazie ad un’appropriata

funzione user-space, così come descritto nel precedente capitolo;

- l’analisi dei risultati, che si basa su una serie di strumenti statistici in grado di

rilevare eventuali trend nell’uso delle risorse e di individuare i parametri più

significativi del carico del sistema.

Page 89: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

82

4.1 Design of Experiments (DoE)

Prima di descrivere il metodo implementato per l’analisi dell’aging nel kernel Linux, si

ritiene opportuno fissare alcune nozioni di base circa il metodo sperimentale [23].

Si può definire statistica la scienza del problem solving in presenza di fattori variabili. Per

variabile si deve intendere una caratteristica, riguardante una peculiare informazione, che

può essere ottenuta tramite un esperimento. In generale, si possono classificare le variabili

in due categorie:

- response variable (variabili di risposta) o variabili dipendenti, che costituiscono il

risultato dell’esperimento stesso;

- fattori o variabili indipendenti, che sono controllabili ed influenzano il valore delle

precedenti.

In tal contesto, un esperimento è un insieme di osservazioni, effettuate per verificare

l’eventuale validità di un’ipotesi riguardante il fenomeno in esame. Per osservazione si

intende, quindi, la collezione di informazioni, ovvero dei valori delle variabili di risposta

ottenuti nell’esperimento.

L’osservazione dei dati costituisce il fulcro del metodo sperimentale. Tutte le informazioni

raccolte sono soggette ad una certa variabilità della propria sorgente che induce variazioni

nelle misure. Le cause di tale variabilità sono disparate e comprendono, in ambito

informatico, lievi differenze fra le macchine, difformità casuali dovute a cambiamenti nelle

condizioni ambientali, errori di misura originati da fattori random o dalla poca sensibilità

degli strumenti utilizzati (ad esempio, per quel che riguarda la misura dei cicli di clock

impiegati per effettuare una certa operazione), ecc.. Ne deriva che la progettazione degli

esperimenti è una fase delicata e complessa che dovrebbe mirare il più possibile a mitigare

le conseguenze degli errori presenti nelle misurazioni.

Una metodologia finalizzata ad un buona progettazione degli esperimenti è stata esposta

già da Fisher nel 1935 [24]. Questi identifica le seguenti caratteristiche come peculiari di

un buon metodo sperimentale:

- comparison (confronto), cioè il confronto tra treatment differenti, dove con il termine

Page 90: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

83

trattamento si indicano le condizioni in cui viene effettuata una prova sperimentale;

- randomization (casualità), che consiste nel rendere casuali le condizioni di una serie

di esperimenti correlati. Supponendo che il numero di tali prove sia adeguato per

spiegare statisticamente il fenomeno oggetto di studio, la casualità fa sì che gli effetti

di fenomeni di disturbo risultino mediati su tutti gli esperimenti e possano inoltre

essere stimati con metodi probabilistici;

- replication (replicazione), cioè la ripetizione delle prove sperimentali, che

dovrebbero aumentare al crescere delle fonti di variabilità del fenomeno in esame.

Nella pratica non è sempre possibile rispettare il principio di replicazione. Ad

esempio, se il costo legato ad ogni singola prova è proibitivo oppure ciascun

esperimento richiede un tempo molto lungo per essere eseguito, si cerca di ridurre il

più possibile il numero delle prove. Ciò conduce ad un risparmio nei costi che si

ripercuote però inevitabilmente sull’affidabilità dei risultati;

- blocking (clustering), ossia il raggruppamento dei risultati delle misure in gruppi

caratterizzati da specifiche proprietà comuni, con lo scopo di rilevare con più

precisione le sorgenti di variabilità.

Sulla scia degli studi di Fisher, si è sviluppato un vero e proprio filone scientifico

dedicato alla definizione di buone procedure sperimentali. In tale ottica, si può definire

Design of Experiments (DoE) [25], il processo di pianificazione, progetto ed analisi degli

esperimenti condotti per vagliare una certa ipotesi riguardo ad un fenomeno d’interesse. Il

DoE ha lo scopo di guidare il lavoro dello sperimentatore, in modo che questi sia in grado

di trarre conclusioni valide ed oggettive, in maniera efficace ed efficiente.

In contesti industriali di applicazione del DoE, si distinguono due tipologie di variabili

indipendenti:

- fattori quantitativi (ad esempio, velocità, tempo, temperatura, ecc.), di cui va scelto il

range di settaggio e la modalità di misura e controllo durante l’esperimento;

- fattori qualitativi (ad esempio, tipi di materiali, tipi di hardware, tipi di sistemi

operativi da impiegare per testare un software, ecc.), che possono assumere solo

Page 91: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

84

valori discreti e, quindi, risultano anche più semplici da settare, misurare e

controllare.

A seconda della tipologia della variabili dipendenti, in fase di progettazione degli

esperimenti, è necessario decidere il numero dei cosiddetti livelli da assegnare a ciascun

fattore in ogni prova, dove per livello si intende uno specifico valore o settaggio attribuito

ad un fattore. Nella terminologia DoE, un trial o run (talvolta anche treatment) identifica

una certa combinazione di livelli dei fattori che influenzano l’output della prova. Il numero

di trial richiesti per stimare gli effetti dei fattori sulle variabili di risposta è determinato dal

numero stesso delle variabili indipendenti e da quello dei possibili livelli che ciascuna può

assumere. Se, ad esempio, sono dati k fattori qualitativi ad l livelli, il numero di run

esaustivo è n=lk. Sono state comunque definite moltissime tecniche per rendere più efficaci

le prove e per far sì che non sia sempre necessario un numero troppo elevato di

esperimenti. I tre principi fondamentali del DoE, randomizzazione, replicazione e

clustering, sono appunto applicati per ridurre gli errori sperimentali e per rendere più

significativa ogni prova.

La progettazione degli esperimenti dovrebbe articolarsi, indipendentemente dal contesto

d’impiego, nelle seguenti fasi:

- individuazione dell’obiettivo della sperimentazione attraverso la definizione di una o

più response variable;

- scelta di un set di fattori, che potenzialmente influenzano il risultato;

- pianificazione del numero e della tipologia delle prove da eseguire;

- analisi dei risultati, volta ad individuare la dipendenza delle variabili dipendenti da

quelle indipendenti, separando l’effetto di queste ultime dal cosiddetto residuo,

ovvero dalle conseguenze di elementi non direttamente controllabili.

Le tecniche più largamente utilizzate nella programmazione degli esperimenti sono [26]:

- gli esperimenti fattoriali, in cui ciascuno dei fattori viene considerato a due livelli;

Page 92: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

85

- la metodologia delle superfici di risposta, usata per la modellazione e l’analisi di

applicazioni il cui obiettivo è l’ottimizzazione di una certa risposta di interesse,

influenzata da un determinato numero di variabili di ingresso;

- il metodo di Taguchi, che ritiene la varianza delle variabili di risposta dipendente da

almeno alcuni dei fattori. Tale approccio si propone, quindi, di individuare per via

sperimentale le condizioni di produzione ottima della variabile dipendente (cioè

quelle in grado di garantire un livello medio della risposta pari ad un valore

prefissato ed una sua varianza che sia insensibile alle diverse fonti di variabilità).

Poiché le tecniche DoE si fondano su metodi statistici, esse sono spesso complesse e

richiedono un certo dispendio di costi sia in fase di progettazione che di attuazione. Per tali

ragioni, a volte, questi strumenti non vengono utilizzati nelle industrie manifatturiere o

magari non se ne sfruttano le piene potenzialità. In ogni caso, bisogna tener presente che il

DoE può condurre, in tempi brevi, a miglioramenti successivi nella qualità di un prodotto o

nell’efficienza di un processo. Per l’utilizzo corretto della metodologia dovrebbero essere

ben chiari 8 concetti fondamentali [27]:

- stabilire dei buoni obiettivi, anche per quel che riguarda la scelta delle variabili da

settare e monitorare;

- cercare di misurare le variabili di risposta in modo quantitativo (evitando ad esempio

di basarsi su giudizi soggettivi della qualità di un prodotto);

- condurre un opportuno numero di repliche per smorzare gli effetti di fattori di

rumore;

- randomizzare il run order, ossia l’ordine in cui si conducono gli esperimenti, al fine

di mitigare l’influenza dalle variabili incontrollate (ad esempio, l’usura

dell’attrezzatura, la temperatura dell’ambiente, le variazioni della materia prima,

ecc.);

- escludere le fonti conosciute di variazione;

- tener presente gli eventuali effetti confusi (una confusione indica che si sono

cambiate due o più cose allo stesso tempo nello stesso modo);

Page 93: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

86

- condurre una serie sequenziale di esperimenti in modo ripetitivo e standardizzato;

- confermare sempre i risultati critici.

Per quanto concerne l’applicazione del DoE nell’analisi di tipo mesurement-based

dell’aging in un software, si deve innanzitutto stabilire quali fattori (parametri di workload)

a livello applicativo possono essere controllati dall’utente che esegue l’esperimento. Una

volta definiti i parametri controllabili, è necessario identificare le variabili da monitorare a

livello target (nel nostro caso, a livello di SO).

L’esecuzione degli esperimenti può, dunque, essere così definita:

- scelta dei fattori controllabili riguardanti il workload imposto al sistema per ogni

esperimento;

- definizione del numero n di livelli da assegnare ai fattori controllabili;

- scelta di un intervallo di tempo per il campionamento di informazioni relative

all’utilizzo delle risorse di sistema e dei parametri di workload durante ogni

esperimento;

- attuazione di un definito numero di prove, condotte collezionando le informazioni

suddette.

Nei paragrafi che seguono viene descritta la procedura sperimentale utilizzata per lo

studio del software aging nel kernel Linux. Come si vedrà, sebbene si sia cercato di

attenersi ai buoni principi del DoE per rendere sistematica e disciplinata la

sperimentazione, non è stato possibile rispettarne tutti i dettami. In particolar modo, poiché

l’analisi deve riguardare SO long running, non si può effettuare, con costi e tempi

contenuti, un gran numero di test. Si è cercato allora di preservare la validità dei risultati

ottenuti garantendo una certa randomizzazione a livello applicativo. In pratica, il tool

utilizzato per lo stress del sistema (cfr. paragrafo 4.3) fa in modo che le operazioni

richieste al kernel siano casualmente variabili entro certi parametri stabiliti dallo

sperimentatore. Questa variabilità riguarda il numero, il tipo e la tempificazione delle

operazioni effettuate in ciascuna unità temporale.

Page 94: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

87

Relativamente all’approccio sperimentale adottato, i parametri di workload di alto livello

(cioè quelli settati tramite il tool di stress) coincidono con i fattori controllabili della

terminologia DoE. Tuttavia, l’obiettivo è quello di studiare l’aging nel SO

indipendentemente dalle caratteristiche di alto livello del workload. Ciò può avere lo

scopo, ad esempio, di applicare tecniche di TTE estimation delle risorse senza conoscere

ed instrumentare applicazioni. Per tali motivi, occorre caratterizzare il carico del sistema

raccogliendo delle misure a basso livello, attraverso un opportuno strumento di monitoring

(il tracer, appunto). Questo procedimento consente di associare ad una ben definita

esecuzione di un esperimento le misurazioni che la caratterizzano. Tale caratterizzazione

può poi essere messa in corrispondenza con il trend di aging rilevato nel test. A valle di

queste operazioni, si potrebbe infine effettuare un’analisi di sensitività del trend di aging

verso i parametri di basso livello.

4.2 Software aging nel kernel Linux: procedura sperimentale

La procedura sperimentale per l’analisi del fenomeno di aging nel kernel Linux è stata

suddivisa nelle seguenti macrofasi (riportate in figura 4.1):

- individuazione delle aree da monitorare, che consiste nell’identificare i sottosistemi

del kernel di interesse e le informazioni ad essi relative;

- realizzazione di un tracer, myTracer.c, per il tracciamento delle informazioni di

sistema. Tale componente ha il compito di reperire periodicamente i dati definiti al

passo precedente e di scriverli in un apposito buffer circolare (ring buffer) in kernel

space (quindi non direttamente accessibile da applicazioni utente);

- realizzazione di una funzione in user space, myTracer-rep.c, la quale ha il

compito di rendere disponibili allo sperimentatore le informazioni collezionate dal

tracer. In particolar modo, questa funzione formatta in maniera più leggibile i dati,

distribuendoli ordinatamente in un insieme di file;

- progettazione e realizzazione degli esperimenti;

Page 95: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

88

- software aging analysis, che ha lo scopo di valutare eventuali trend di aging

relativamente ai vari sottosistemi nonché l’influenza dei parametri di workload sui

trend individuati.

Figura 4.1: modello procedurale per lo studio del software aging.

I primi tre step sono stati illustrati nel capitolo precedente. Nei paragrafi che seguono ci si

propone, allora, di descrivere nei dettagli la procedura sperimentale proposta con la relativa

analisi dei risultati raccolti.

Page 96: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

89

4.3 Progettazione degli esperimenti

Come si è detto, l’aging si manifesta in software long running con la progressiva

diminuzione delle risorse computazionali disponibili, dovuta all’accumulo in un lungo

periodo di tempo di potenziali condizioni di errore. Ne deriva che l’analisi del fenomeno

dovrebbe basarsi su osservazioni lunghe, di durata dipendente dalla vulnerabilità del

sistema in esame rispetto all’aging.

Per evitare, allora, di condurre esperimenti eccessivamente onerosi, che osservino il kernel

in situazioni di lavoro ordinarie per settimane o anche mesi, si può pensare di imporre un

carico elevato al sistema in modo da forzarne un più veloce degrado, che risulti osservabile

in pochi giorni. In particolare, la scelta puntuale del workload può essere effettuata con un

apposito capacity test, mirato a determinare il valore limite del carico per cui si osservi un

progressivo esaurimento delle risorse che sia imputabile al solo fenomeno dell’aging (e

non alla condizione di lavoro). In altri termini, vanno eseguite prove successive che varino

il workload (facendolo diminuire a partire da un valore massimo che conduca presto il

sistema al crash non attribuibile all’aging) fino ad un livello che possa essere considerato

critico (cioè che permetta di osservare un degrado in pochi giorni) ma non eccessivo (ossia

tale da provocare immediatamente fallimenti non imputabili all’aging).

Per impostare un adeguato carico di lavoro, è stato così utilizzato il tool open source

stress fornito come pacchetto aggiuntivo per Linux. Tale componente consente di

configurare il workload relativo alla CPU, alla memoria, all’I/O, al disco rigido e così via.

Stress non è un vero e proprio strumento di benchmark, poiché non effettua misurazioni

e statistiche ma si limita ad inviare al SO definite quantità di carico, in modo da consentire

agli utenti di analizzare caratteristiche di performance dell’intero sistema o di specifiche

componenti.

Come è possibile leggere digitando il comando man stress, Il tool va attivato attraverso

la seguente istruzione:

stress [OPZIONE [ARGOMENTO]] .

Le opzioni più importanti sono:

Page 97: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

90

- –version, che indica la versione del tool;

- -v (verbose), che consente di visualizzare passo dopo passo le operazioni eseguite

durante lo stress;

- -t N (timeout), che permette di terminare lo stress dopo la scadenza di un timeout

impostato ad N secondi;

- --backoff N, che consente di impostare un timer ad N microsecondi, alla scadenza

del quale parte l’attività di stress del sistema;

- -c N, che imposta N worker per lo stress della CPU richiamando a ripetizione la

funzione per il calcolo della radice quadrata sqrt();

- -i N, che imposta N worker per sforzare il sottosistema di I/O attraverso

l’operazione sync();

- -m N, che definisce N worker per l’esecuzione delle operazioni di allocazione e

deallocazione della memoria, utilizzando le funzioni malloc() e free();

- --vm-bytes B, che alloca B byte per gli m worker (di default è B=256 MB);

- --vm-stride B, che accede ad un byte di dati ogni B byte (di default è B=4096

MB);

- --vm-hang N, che addormenta per N secondi il processo prima di liberare la

memoria allocata;

- --vm-keep, che reindirizza la memoria invece di liberarla e riallocarla;

- -d N, che definisce N worker per le operazioni di write() ed unlink();

- --hdd-bytes B, che scrive B byte per i worker definiti al punto precedente ( di

default è B=1GB).

Attraverso un opportuno settaggio delle opzioni disponibili (cfr. paragrafo 5.1), è stato così

possibile impostare il carico per l’esperimento condotto in maniera estremamente

semplice. Contestualmente, tramite la sequenza di comandi presentata nel paragrafo 3.4,

sono stati attivati il tracer e la funzione in user space per il reperimento delle informazioni

di sistema. Questa organizzazione fa sì che, anche attraverso un unico esperimento, sia

Page 98: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

91

possibile ottenere misure valide, pur se non del tutto generali, riguardo ad eventuali trend

di aging.

4.3.1 Analisi di software aging

L’ultimo step della procedura seguita consiste nella rilevazione e stima di eventuali

trend di aging, relativamente all’utilizzo delle risorse, e nell’analisi della relazione tra

questi ed il workload, caratterizzato nello step precedente. Il procedimento che è stato

impiegato per eseguire tale valutazione è rappresentato in figura 4.2.

Figure 4.2: processo di elaborazione delle informazioni di sistema.

La prima fase consiste nella raccolta dei dati a partire dai file resi disponibili dalla funzione

myTracer-rep.c. Le informazioni collezionate sono state sottoposte ad un preventivo

preprocessing (cfr. paragrafo 4.3.1.1) al fine di renderle fra loro omogenee e di ricavare le

Page 99: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

92

stime di throughput loss e time loss a partire dai vettori di latenza relativi alle system call

monitorate.

A questo punto è stato possibile procedere alla vera e propria analisi dei dati che è stata

espletata in 3 fasi successive:

- la verifica della presenza di trend di aging tramite test di Mann-Kendall e

determinazione dello slope attraverso la tecnica proposta da Sen;

- la Principal Component Analysis (PCA) per decorrelare i parametri di tracing ed

esprimere in maniera più compatta (con meno variabili) le informazioni in essi

contenute;

- individuazione dei coefficienti più rilevanti delle componenti principali più

significative, in modo da definire una relazione tra i parametri di workload e il trend

di aging per il particolare esperimento condotto.

4.3.1.1 Raccolta dei dati e preprocessing

Tramite apposite funzioni Matlab, sono stati letti i dati di sistema che risultano suddivisi

in 3 grupi:

- freeMem.txt, che contiene il vettore FM relativo ai valori campionati della

memoria libera disponibile;

- 5 file che tengono traccia dei parametri di tracing per sottosistema (mem.txt,

proc.txt, disk.txt, net.txt e filesystem.txt);

- 12 file che contengono i tempi di latenza relativi ad altrettante system call

(access.txt, brk.txt, clone.txt, close.txt, exec.txt, fork.txt,

lseek.txt, mmap.txt, munmap.txt, open.txt, read.txt, write.txt).

Questi ultimi sono stati distribuiti in 3 sottogruppi, contenenti ciascuno le informazioni

relative alle system call specifiche di uno dei 3 sottosistemi del kernel di memory, process

e file system management. Per il sottosistema driver control non è stato previsto il

monitoring di alcuna system call, mentre il sottosistema di networking è stato escluso

Page 100: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

93

dall’esperimento condotto per le motivazioni indicate nell’introduzione al prossimo

capitolo. A partire da ogni sottogruppo sono stati poi definiti i seguenti vettori:

- TLM, TLP e TLF, contenenti i dati di throughput loss per i 3 sottosistemi del kernel;

- MTM, MTP e MTF, rappresentanti le informazioni di time loss per i sottosistemi.

In particolar modo, il calcolo dei primi 3 vettori consiste semplicemente nella somma, riga

per riga, dei valori di latenza ricavati dal sottogruppo relativo di file. Si tenga presente che

ogni file originale contiene, su ciascuna riga, il numero di chiamate di sistema di un unico

tipo servite in uno specifico evento (della durata di 5 minuti) entro un tempo determinato

dalla posizione considerata. Ad esempio, la prima riga del file mmap.txt contiene, nella

prima posizione, il numero di system call mmap con latenza compresa fra 25 e 26 cicli di

clock, nella seconda quelle servite fra 26 e 27 cicli, ecc.. Ne deriva che, sommando gli

elementi di ogni riga, si determina il numero totale di chiamate di sistema mmap eseguite in

ogni specifico evento. Quindi, per calcolare l’indicatore di throughput loss riguardante, ad

esempio, il sottosistema di memory management, è sufficiente sommare i valori di ogni

riga dei file relativi alle system call mmap.txt, munmap.txt e brk.txt e poi

addizionare le somme ottenute. Si avrà dunque:

.num_eventi1per ,),(),(),(32

1

32

1

32

1≤≤++= ∑∑∑

===

ijibrkjimunmapjimmapTLMjjj

i

Con la stessa procedura sono stati calcolati i vettori TLP e TLF.

Per quanto riguarda, invece, gli array relativi al time loss, ciascuno di essi rappresenta il

tempo medio di servizio delle system call appartenenti ad un dato sottosistema (nell’evento

di tracing considerato). Quindi, le righe i-esime di ogni file originale vanno innanzitutto

sommate ed il vettore ottenuto deve essere moltiplicato scalarmente con un array di pesi

esponenziali. Il valore risultante va infine diviso per la somma delle operazioni eseguite in

quell’evento, cioè per iTLM . Ad esempio, relativamente al sottosistema di memory

management, è stato calcolato:

Page 101: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

94

[ ]

.num_eventi1per ,),(),(),(

2

2

2

:),(:),(:),(

32

1

32

1

32

1

37

6

5

≤≤++

⎥⎥⎥⎥⎥⎥

⎢⎢⎢⎢⎢⎢

×++

=

∑∑∑===

ijibrkjimunmapjimmap

ibrkimunmapimmap

MTM

jjj

i

Le operazioni appena descritte hanno permesso di ricavare gli indicatori di aging che si

aggiungono a quello di memory depletion.

A questo punto tutti i dati raccolti (parametri di tracing ed indicatori di aging), per

essere espressi in unità omogenee, sono stati sottoposti ad una normalizzazione preventiva

con la formula:

{ }{ } { }xx

xxx

evento evento

evento

minmax

min

∀∀

−=′

dove x′ rappresenta il valore normalizzato di x e { }xevento

min∀

(max) indica il minimo

(massimo) valore che x in un determinato evento. Tale trasformazione permette di far

ricadere tutte le variabili nel range di valori compreso tra 0 e 1.

In ultimo, si è ritenuto opportuno eliminare (ossia sostituire con la media della serie) i

campioni a grande distanza dal valor medio (outliers) poiché questi rappresentano

osservazioni rare ed isolate, dovute a fattori non controllabili, che non sono rappresentative

del problema.

4.3.1.2 Test di Mann-Kendall e metodo di Sen

Il primo passo dell’analisi dei risultati sperimentali consiste nel verificare l’esistenza di

trend di aging a partire dai 7 indicatori precedentemente decritti, FM, MTM, MTP, MTF, TLM,

TLP e TLF, contenenti informazioni di sistema campionate periodicamente ogni 5 minuti.

Page 102: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

95

A tale scopo è stato utilizzato il test non parametrico di Mann-Kendall [30, 31], che

consente di ricercare la presenza di trend di lungo periodo, senza la necessità di fare

assunzioni sulla forma della distribuzione dei dati. In generale, i test non parametrici

costituiscono uno strumento statistico potente in quanto il risultato è minimamente

influenzato dalla presenza di eventuali outlier nelle serie di dati.

L’ipotesi nulla del test di Mann-Kendall suppone l’assenza di trend nell’insieme di dati da

cui è estratto il dataset oggetto di indagine. Secondo l’ipotesi alternativa, invece, è corretto

affermare che nella serie analizzata è presente un trend crescente o descrescente. La

statistica S di Mann-Kendall viene calcolata attraverso la seguente espressione:

∑ ∑−

= +=

−=1

1 1)(

n

i

n

ijij yysignS

dove yi ed yj rappresentano i valori definiti nella serie alle posizioni i e j rispettivamente, n

indica la lunghezza del dataset e

( )⎪⎪⎩

⎪⎪⎨

<−

=

>

=

0,1

0,0

0,1

ϑ

ϑ

ϑ

ϑ

se

se

se

sign .

Sotto l’ipotesi che le y siano indipendenti ed identicamente distribuite, per n≥10, la

statistica è ben interpretata da una distribuzione normale, con media nulla e varianza pari a:

( )( )18

5212 +−=

nnnσ .

Pertanto, definita la statistica test standardizzata Z come

⎪⎪⎪

⎪⎪⎪

<+

=

>−

=

0 se ,1

0 se ,0

0 se ,1

SS

S

SS

Z

σ

σ

,

Page 103: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

96

la significatività del trend viene testata tramite il confronto di Z con una distribuzione

guassiana normalizzata, ad un desiderato livello di confidenza (nel caso implementato

impostato al 95%).

Per tutte le serie relative agli indicatori di aging, può essere inoltre calcolata una grandezza

rappresentativa della confidenza del trend. Tale quantità, indicata con il termine di p-value,

diminuisce all’aumentare del livello di confidenza. Quindi, se p-value è prossima a zero,

viene indicata una forte evidenza contro l’ipotesi nulla (ciò significa che, con grande

probabilità, c’è un trend di aging), mentre valori elevati forniscono un’evidenza a favore di

quest’ultima (cioè non è presente alcun trend).

Inoltre, una stima robusta del coefficiente angolare β  della retta interpolante i dati può

essere effettuata attraverso il metodo di Sen che utilizza la seguente espressione:

( )ji

ijyy

Mediana ij <∀⎥⎦

⎤⎢⎣

⎡−

−= β .

Nel caso di studio, il test di Mann-Kendall è stato effettuato sui 7 indicatori di aging

attraverso la funzione Matlab denominata ktaub1 che prende in input:

- il vettore bidimensionale contenente la serie dei dati su cui effettuare il test;

- l’indice da cui si intende partire per l’analisi della serie (1 se si vuole considerare

l’intero dataset, 2 se si intende cominciare dal secondo campione, ecc.);

- il coefficiente di confidenza;

- un flag per indicare se si desidera visualizzare il plot del trend.

In output, ktaub fornisce una serie di informazioni tra cui:

- i valori delle statistiche S e Z;

- la deviazione standard dei dati;

- un flag h che indica l’ipotesi verificata nel test (se h=0 allora risulta verificata

l’ipotesi nulla; se, invece, h=1 il trend è significativo);

- il p-value;

1 http://www.mathworks.com/matlabcentral/fileexchange/22389-seasonal-kendall-test-with-slope-for-serial-

dependent-data

Page 104: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

97

- la stima del coefficiente angolare delle retta interpolante il dataset (slope), calcolato

tramite metodo di Sen. Se tale valore è positivo, allora il trend individuato è

crescente; in caso contrario esso è decrescente.

Quest’ultimo valore fornisce informazioni interessanti circa l’evoluzione futura del

sistema. In particolare, valutare lo slope in caso di aging serve:

- per l’indicatore di memory depletion, a stimare il periodo in cui non si avrà più a

disposizione alcuna locazione di memoria libera (cioè a valutare il TTE relativo alla

memoria);

- per il throughput loss e per il time loss, a quantificare l’andamento del livello di

prestazione del sistema e, quindi, a valutare il tempo impiegato affinché le

performance scendano sotto un livello accettabile.

4.3.1.3 Principal component analysis

In generale, non è ragionevole assumere che i dati restituiti dall’architettura di tracing

siano incorrelati, poiché le informazioni di sistema dipendono nel loro complesso dal

carico applicato e dalla configurazione hardware/software e sono, perciò, connesse. Per

rimuovere la correlazione intrinseca nei dati collezionati, è stata allora utilizzata la

Principal Component Analysis (PCA) [32], che trasforma le variabili originali in

componenti incorrelate, dette appunto Componenti Principali (PC).

L’analisi delle componenti principali o trasformazione di Karhunen-Loeve è una tecnica di

estrazione di feature basata sul criterio dell’errore quadratico medio, che costituisce un

approccio classico alla riduzione della dimensionalità di un problema ed alla separazione

delle sorgenti. A partire da m feature generiche X1, X2, …, Xm, la PCA origina (attraverso

procedimenti algebrici che trascureremo per brevità) un insieme di (al più) m feature

incorrelate PC1, PC2, …, PCm (che costituiscono altrettante stime delle sorgenti), cioè

aventi la matrice di covarianza diagonale. Tali componenti principali possono essere

espresse come combinazioni lineari delle variabili iniziali, cioè:

Page 105: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

98

∑=

=m

jjiji XcoefPC

1,

dove i coefficienti coefij appartengono al range [-1,1]. Se coefij, in modulo, è molto vicino

ad 1, allora la PC i-esima rappresenta buona parte del contenuto informativo di Xj;

viceversa, se coefij è prossimo a zero, significa che PCi non dipende in maniera rilevante

dalla variabile originale j-esima.

La trasformazione gode delle seguenti proprietà:

- Var[PC1] > Var[PC2] > . . . > Var[PCm], cioè le PC risultano ordinate nel senso

decrescente della varianza. Ciò significa, ad esempio, che PC1 contiene più

informazione utile rispetto a PCm;

- Cov(PCi, PCj) = 0 per ogni i ≠ j, cioè le componenti principali sono incorrelate.

Questo implica che ciascuna rappresenta informazioni differenti rispetto alle altre;

- [ ] [ ]∑∑==

=m

ii

m

ii XVarPCVar

11, cioè non c’è perdita di informazione nel passaggio dalle

variabili iniziali alle PC. Tuttavia, poiché la varianza delle componenti principali

risulta concentrata fortemente nelle prime PC, si può utilizzare un numero ridotto di

variabili per rappresentare gran parte del contenuto informativo del dataset iniziale.

La principal component analysis sui parametri di aging è stata effettuata utilizzando la

funzione di libreria Matlab princomp avente prototipo:

[COEFF, SCORE, LATENT] = princomp(X)

Il parametro di input X rappresenta una matrice N×P le cui colonne corrispondono alle

variabili originali e le cui righe alle osservazioni di queste. La matrice d’uscita COEFF,

invece, contiene i coefficienti delle combinazioni lineari coefij, tramite cui è possibile

ricavare le PC a partire dalle variabili iniziali. Le colonne di tale matrice sono ordinate per

valori decrescenti della varianza delle PC cui si riferiscono. La tabella SCORE restituisce le

rappresentazioni delle variabili X come combinazioni lineari delle componenti principali,

mentre LATENT è un vettore contenente i valori di varianza delle PC.

Page 106: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

99

I parametri di tracing, opportunamente suddivisi per sottosistemi, sono stati sottoposti a

PCA con princomp. Le PC così ottenute rappresentano variabili non ridondanti (poiché

esse sono incorrelate). È stato poi selezionato solo un sottoinsieme delle componenti

principali { }qiiPC 1= , in grado di rappresentare la maggior parte della varianza dei dati

iniziali (98%). A partire da tali PC (che rappresentano la quasi totalità del contenuto

informativo dei dati iniziali ma non hanno significato fisico), sono stati quindi individuati i

coefficienti di combinazione lineare più significativi, al fine di determinare quali parametri

di workload hanno pesato maggiormente sulla composizione di ciascuna PC e risultano,

quindi, più rilevanti per la caratterizzazione del workload.

Page 107: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

100

Capitolo 5 Sperimentazione ed analisi dei risultati

Nel presente capitolo si illustra un esempio della procedura proposta che consente di

analizzare e valutare i dati restituiti dallo strumento di tracing durante un particolare

esperimento. Una volta definito l’ambiente di sviluppo, quello di esecuzione dei test ed i

tool utilizzati, si spiega il modo in cui è possibile valutare eventuali trend di aging, stimare

il TTE di alcune risorse e determinare i parametri di workload più significativi.

L’esecuzione di un esperimento viene condotta essenzialmente in tre fasi:

- abilitando lo strumento di monitoring;

- impostando il workload tramite il tool stress ed attivando i meccanismi di tracing

per la raccolta delle informazioni di sistema;

- analizzando i risultati con l’ausilio di apposite procedure definite in ambiente

Matlab.

È necessario sottolineare che, poiché stress non consente di stabilire il carico del

sottosistema di networking, sarebbe necessario eseguire l’esperimento tramite l’attivazione

simultanea di un secondo strumento di benchmark. Tuttavia, per limitare l’overhead e gli

effetti di aging dovuti a cause esterne al SO, nell’esempio mostrato si è scelto di non

utilizzare un ulteriore tool e di tralasciare quindi lo studio del sottosistema di network I/O.

Inoltre, relativamente al sottosistema di device control, è stato stressata solo la parte

relativa all’I/O da/verso il disco. Pertanto, nei prossimi paragrafi, ci si riferisce a tale

porzione monitorata con la locuzione “sottosistema disk I/O driver”.

Page 108: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

101

5.1 Esecuzione del test

I test per lo studio del software aging sono stati eseguiti utilizzando la distribuzione

Linux Reh Hat 4, con versione del kernel 2.6.30.1.

Figura 5.1: procedura sperimentale.

Dalla figura 5.1 è possibile evincere, in maniera schematica, l’interazione tra lo

sperimentatore e gli strumenti utilizzati per la cattura e l’elaborazione delle informazioni.

In particolare, l’utente, una volta attivato il tool stress, deve semplicemente abilitare il

tracing del kernel e la funzione per il reperimento periodico dello stato del SO. Una volta

terminato il test, lo sperimentatore è poi in grado di effettuare elaborazioni sui dati raccolti

avviando uno script Matlab opportunamente programmato. Esso consente di eseguire le

operazioni statistiche illustrate nel capitolo 4, al fine di permettere opportune valutazioni

sul fenomeno di aging. Lo script richiama apposite procedure che consentono di ottenere i

risultati parziali dell’analisi.

Page 109: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

102

In particolare, in figura 5.2 vengono esemplificati i passi seguiti per l’elaborazione delle

informazioni raccolte, ciascuno corrispondente ad una specifica funzione Matlab e

descritto nel capitolo 4. La prima fase consiste nel recuperare le informazioni sui parametri

di workload, salvate nei file relativi dalla funzione myTracer-rep.c. Una volta acquisiti,

questi dati vengono normalizzati e da essi sono scartati i valori outlier. Nello step

successivo si provvede alla costruzione delle serie di dati, corrispondenti agli indicatori di

aging, da sottoporre al test di Mann Kendall (al fine di rilevare eventuali trend di aging e di

stimare lo slope del trend che consente poi di effettuare le TTE estimation) e alla PCA. I

risultati di quest’ultimo passo consentono di determinare i parametri di workload più

rilevanti per i trend di aging individuati.

Figura 5.2: procedura di analisi dei dati.

L’esperimento d’esempio è stato condotto eseguendo in maniera sequenziale un ben

definito insieme di operazioni:

- settaggio del carico di lavoro da imporre alla macchina e scelta del tempo totale di

esecuzione;

Page 110: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

103

- abilitazione del tracer myTracer;

- attivazione della funzione myTracer-rep per il reperimento delle informazioni in

user space;

- esecuzione del test per un tempo minimo di 5 giorni;

- elaborazione dei dati attraverso lo script Matlab;

- valutazione dei risultati.

Il workload applicato è stato stabilito attraverso la seguente istruzione:

stress -c 50 -i 50 -m 100 --vm-bytes 4M --hdd 100 --hdd-bytes 4M –t 7d .

I valori assegnati ai parametri configurabili del tool sono stati scelti in modo tale da

stressare in maniera abbastanza significativa il sistema. Tale scelta è stata fatta al fine di

individuare più velocemente possibile eventuali trend, cercando però di non indurre un

prematuro esaurimento delle risorse. In particolare, attraverso la precedente istruzione si è

stabilito di utilizzare:

- 50 processi per lo stress relativo alla CPU;

- 50 processi per le operazioni di I/O;

- 100 processi per le operazioni di malloc e free sulla memoria, ognuno dei quali

alloca e libera blocchi di 4 MB;

- 100 processi per l’esecuzione di operazioni di write ed unlink, ognuno dei quali

scrive una quantità di informazioni pari a 4 MB.

Inoltre, la durata complessiva dell’esperimento è stata impostata a 7 giorni in via

precauzionale ma i trend di aging si sono manifestati in anticipo, cosicché è stato possibile

interrompere il test dopo 5 giorni 6 ore e qualche minuto.

5.1.1 Individuazione dei trend di aging

I trend di aging, come spiegato in precedenza, sono stati individuati attraverso la

funzione Matlab ktaub. In particolare, a partire dalle informazioni riguardanti la memoria

libera disponibile, la latenza ed il numero di system call servite durante il periodo di

Page 111: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

104

osservazione, è stato possibile analizzare i trend relativi ai 7 indicatori di aging considerati,

ottenendo i risultati che seguono.

Memory depletion

Analizzando il contenuto del file freeMem.txt è stato possibile osservare, come

mostrato in figura 5.3, la variazione di memoria libera disponibile durante l’intera

esecuzione dell’esperimento.

Figura 5.3: variazione memoria fisica libera disponibile.

In figura 5.4 si riporta il grafico del trend relativo all’indicatore di memory depletion (linea

in verde), ottenuto utilizzando la funzione Matlab ktaub. Esso risulta significativo al 95%

con coefficiente angolare della retta interpolante pari a -0.5267×10-5 kB/min.

Page 112: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

105

Figura 5.4: trend relativo all’indicatore di memory depletion.

Throughput loss

Tale indicatore di aging è stato calcolato basandosi sul numero di system call (sotto

osservazione) servite al minuto, così come spiegato nel paragrafo 4.3.1.1. Dei 3 indicatori

di throughput loss, l’unico che presenta un trend significativo è quello relativo al

sottosistema di memory management, così come riporta la figura 5.5.

Time loss

In maniera analoga al caso precedente, tale indicatore di aging è stato ottenuto in base al

calcolo del tempo medio impiegato dal sistema per servire un insieme di system call (cfr.

paragrafo 4.3.1.1). Anche in questo caso, risulta significativo esclusivamente il trend

relativo al sottosistema di memory management (figura 5.6). Questi risultati indicano che,

molto probabilmente, il consumo crescente di memoria rende più lente le operazioni

successive di gestione della memoria stessa.

Page 113: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

106

Figura 5.5: trend relativo all’indicatore di throughput loss

del sottosistema memory management.

Figura 5.6: trend relativo all’indicatore di time loss del sottosistema memory management.

Page 114: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

107

Nella tabella 5.1 si riportano, in maniera sintetica, i risultati ottenuti dalle precedenti

analisi.

Parametri T.S. (95%)

Slope (x10-5)

V.P. (in 5 giorni)

TTE (giorni)

Memory depletion [kB/min]

FreeMem SI -0.5267 ≈-7.5% ≈64

Throughput loss filesystem I/O

[op/min]

numero totale di open, close, access,

lseek, read, write

NO - - -

Throughput loss memory

management [op/min]

numero totale di mmap,

munmap, brk SI -0.0063 ≈-11% ≈49

Throughput loss process

management [op/min]

numero totale di exec,

fork, clone NO - - -

Time loss file system I/O

[cicli clock/min]

latenza totale di

open, close, access,

lseek, read, write

NO - - -

Time loss memory management

[cicli clock/min]

latenza totale di

mmap, munmap, brk

SI 0.3537 ≈4.8% ≈100

Time loss process management

[cicli clock/min]

latenza totale di exec, fork,

clone

NO - - -

Tabella 5.1: sintesi risultati ottenuti.

T.S.=trend significativo, V.P.= variazioni percentuali, TTE=Time To Extausion

Per i trend significativi sono stati stimati i TTE delle risorse relative (memoria e numero di

operazioni eseguite). Tale calcolo si basa sulla conoscenza dello slope del trend, il quale

viene restituito da ktaub. Poiché l’equazione della retta interpolante può essere espressa

come

)1(serietemposlopetrend +×= ,

Page 115: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

108

a partire dal valore della pendenza del trend, il TTE (cioè il valore di tempo in

corrispondenza del quale il trend si annulla) è stato calcolato con la seguente formula:

slopeserieTTE )1(−

= ,

dove )1(serie rappresenta il valore dell’intercetta della retta interpolante con l’asse delle

ordinate.

Per quanto riguarda la memory depletion, è stato stimato che il completo esaurimento dello

spazio di memoria, con il workload utilizzato, dovrebbe verificarsi dopo circa 64 giorni,

ipotizzando un trend decrescente in maniera lineare. Per quel che concerne, invece, il

throughput loss si stima un TTE pari a circa 49 giorni. Relativamente, infine, al time loss si

è stimato che in circa 100 giorni il tempo medio impiegato per eseguire le system call

considerate raddoppia.

Nell’arco di tempo d’esecuzione dell’esperimento, sono state infine individuate le seguenti

manifestazioni:

- riduzione della quantità di memoria libera di circa il 7,5%;

- aumento del tempo di esecuzione (indicato in numero di cicli di clock) delle system

call sottoposte a tracing dell’ordine di circa il 4,8%;

- riduzione del throughput di circa l’11%.

5.1.2 Principal component analysis

I parametri di tracing, opportunamente raggruppati per sottosistema, sono stati

sottoposti a PCA in modo da decorrelare e rappresentare con un minor numero di variabili

le informazioni in essi contenute.

Come spiegato nel paragrafo 4.3.1.3, ciò è stato ottenuto con l’ausilio della funzione di

libreria Matlab princomp. Utilizzando l’output relativo al vettore LATENT, fornito in

uscita da tale funzione, è stato possibile selezionare un sottogruppo delle componenti

principali aventi varianza maggiore (cioè le prime). In particolare, sono state scelte le

componenti principali sufficienti a rappresentare almeno il 98% della varianza delle

Page 116: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

109

informazioni originali. Nelle seguenti tabelle vengono riportati, per ogni sottosistema, i

coefficienti di combinazione lineare che legano le componenti principali più significative

ai parametri di workload. A partire da questi, si possono calcolare le PC attraverso il

prodotto scalare con le osservazioni dei parametri di workload X, secondo l’espressione:

∑=

=m

jjiji XcoefPC

1.

Tabella 5.2: coefficienti delle componenti principali relative al sottosistema disk I/O driver.

PC1 PC2 PC3

0.0012 0.0011 -0.4165

-0.0009 0.0007 -0.4183

-0.0010 0.0009 -0.4183

-0.1746 0.4599 0.0188

0.9348 0.3550 0.0042

-0.0646 0.1646 -0.0727

0.0107 0.0024 -0.3582

-0.0010 0.0007 -0.4184

0.0025 0.0042 -0.4084

-0.1747 0.4606 0.0113

-0.1746 0.4599 0.0187

-0.1743 0.4601 -0.0175

Tabella 5.3: coefficienti delle componenti principali relative al sottosistema process management.

PC1 PC2

0.4982 0.0028

0.4982 0.0028

-0.0004 1.0000

0.5059 -0.0026

0.4977 -0.0019

Page 117: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

110

PC1 PC2 PC3

-0.0151 0.4594 -0.1844

-0.0212 0.4579 -0.1833

-0.9992 -0.0377 -0.0121

-0.0094 0.4580 -0.2167

-0.0141 0.4595 -0.2088

-0.0258 0.3961 0.9174

Tabella 5.4: coefficienti delle componenti principali relative al sottosistema file system I/O.

PC1 PC2

-0.0077 -0.1126

-0.0009 -0.0159

-0.0562 -0.6387

-0.0088 -0.0933

-0.0089 -0.0962

-0.0090 -0.0964

-0.0021 -0.0443

-0.0115 -0.1293

-0.0601 -0.7109

-0.0091 -0.1016

-0.0091 -0.1005

-0.7045 0.0607

-0.7045 0.0607

Tabella 5.5: coefficienti delle componenti principali relative al sottosistema memory management.

5.1.3 Valutazione dei risultati

Nelle tabelle precedenti sono stati evidenziati i coefficienti di combinazione lineare

delle PC più significative che superano un preciso valore di soglia. Più precisamente sono

stati selezionati i coefficienti che soddisfano la seguente relazione:

|coeff| ≥ soglia

Page 118: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

111

dove il valore di soglia è stato scelto pari a 0.5 (poiché i coefficienti delle PC variano fra -1

ed 1).

Figura 5.7: composizione della prima e della terza PC relative al sottosistema file system I/O.

Figura 5.8: composizione della prima e dalla seconda PC relative al sottosistema disk I/O driver.

Page 119: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

112

Figura 5.9: composizione della prima e della seconda PC relative al sottosistema memory management.

Figura 5.10: composizione della prima PC relativa al sottosistema process management.

Page 120: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

113

Nelle figure 5.7, 5.8, 5.9 e 5.10 sono raffigurati i coefficienti di combinazione lineare

relativi alle PC maggiormente significative, suddivise per sottosistema. In rosso sono stati

evidenziati i coefficienti che superano (in modulo) il valore di soglia prescelto e che,

quindi, corrispondono ai parametri di workload che più pesano sulla composizione delle

PC considerate.

Dalle figure precedenti si ricavano, in maniera immediata, i parametri di workload più

rilevanti, riportati in tabella 5.6.

File system

I/O

Disk I/O

driver

Memory

management

Process

management

byte_request PC1 nr_access nr_softirq

byte_alloc nr_task_runnable

nr_flush PC2 - nr_tasklet

nr_prelazioni-

PC3 nr_write - - -

Tabella 5.6: parametri di workload più significativi per ogni trend e per ogni sottosistema.

I parametri selezionati influiscono in maniera più significativa rispetto agli altri sui trend di

aging individuati nel test. Da tale assunzione è possibile definire una caratterizzazione del

workload la quale potrebbe consentire, attraverso un elevato numero di esperimenti, di

determinare la variazione dei trend di aging al variare del workload applicato.

Inoltre, l’individuazione di tali parametri permette di riconoscere le aree del kernel che

probabilmente inducono il sistema all’aging e può dunque indirizzare gli sviluppatori del

SO Linux nelle operazioni di debugging (consentendo una sostanziale riduzione dei tempi

e dei costi).

È interessante notare che il fenomeno di aging è stato individuato solo per il sottosistema

di memory management. Ciò indica una probabile vulnerabilità di quest’ultimo. Bisogna

comunque tener presente che tale valutazione non esclude che anche altri sottosistemi

Page 121: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di

software aging nel kernel Linux

114

siano affetti da aging, il quale potrebbe manifestarsi con tempi di sperimentazione più

lunghi e/o carichi di lavoro differenti.

In ultimo è necessario far notare che i TTE dipendono strettamente dal workload e, quindi,

non vanno intesi come metriche generalmente valide. Sicuramente, in condizioni di lavoro

meno pesanti (che sono poi quelle in cui il SO Linux viene utilizzato dagli utenti comuni)

sono necessari tempi consistentemente maggiori per l’eventuale esaurimento delle risorse.

Comunque, l’interesse per il software aging è volto principalmente allo studio del

fenomeno in sistemi long running (che lavorano in situazioni particolarmente critiche sia

per i carichi imposti che per i vincoli di dependability) e, in tali contesti, le valutazioni

effettuate assumono quindi una particolare rilevanza.

Page 122: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

115

Conclusioni e sviluppi futuri

Nel presente lavoro è stata descritta una procedura sperimentale utilizzata per lo studio

del software aging nel kernel Linux. Per attuare una soluzione generale e “leggera”, in

grado di monitorare lo stato del SO senza introdurre consistente overhead, è stato

necessario lo studio attento di molteplici argomenti, tra i quali:

- le definizioni inerenti alla dependability del software e all’aging, al fine di

comprendere a pieno il dominio del problema;

- i lavori già effettuati riguardo alla valutazione dell’invecchiamento nei SO, in modo

da definire lo stato dell’arte ed una base solida da cui partire;

- l’architettura del kernel Linux, per determinarne punti di forza e di vulnerabilità e per

acquisire la giusta competenza necessaria alla programmazione di opportuni

componenti aggiuntivi;

- gli strumenti statistici di uso più comune, necessari per una sperimentazione

disciplinata e valida.

Tramite questi studi è stato possibile acquisire un certo background di conoscenza, che è

stato finalizzato alla progettazione e messa in opera dello strumento di tracing

(implementato in linguaggio C) e del procedimento di sperimentazione ed analisi dei

risultati (realizzato in ambiente Matlab).

Relativamente ad uno specifico carico imposto al sistema, sono stati ottenuti i seguenti

risultati:

Page 123: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

116

- presenza di un trend di aging nel sottosistema di memory management, riguardante

gli indicatori di memory depletion, time loss e throughput loss;

- TTE relativo all’esaurimento della memoria disponibile di circa 64 giorni;

- numero di operazioni eseguite dal SO ridotto a zero in circa 49 giorni;

- tempo di esecuzione delle system call monitorate raddoppiato in circa 100 giorni;

- influenza sui trend da parte dei seguenti parametri di workload

- numero di system call access e write eseguite;

- numero di tasklet e softirq;

- numero di flush e di prelazioni, nonché di byte richiesti ed allocati;

- numero di task “runnable”.

A valle di tali risultati si può concludere che, in condizioni di lavoro particolarmente

stressanti, il kernel Linux dovrebbe essere sottoposto ad interventi di rejuvenation (che

potrebbero concretizzarsi in semplici riavvii) almeno una volta ogni 2 mesi.

Come si è detto, i risultati ottenuti dipendono strettamente dal tipo di carico imposto al

sistema. L’approccio proposto si definisce infatti come mesurement-based e workload-

dependent. Ciononostante, la procedura implementata può essere considerata come il punto

di partenza per studi più approfonditi o rivolti a tipologie differenti di software. In primo

luogo, per esaminare più nel dettaglio l’argomento trattato, andrebbero opportunamente

progettati altri esperimenti, in modo da monitorare le stesse informazioni in condizioni di

carico differenti ed in tempi di testing più lunghi. Una caratterizzazione del workload inter-

esperimento, basata ad esempio su tecniche di clustering, potrebbe in tal caso servire a

comprendere e predire il comportamento di sistema in presenza di condizioni di lavoro

svariate.

Sarebbe inoltre interessante applicare la procedura sperimentale ad altre distribuzioni di

Linux in modo da comprendere se talune vulnerabilità sono state ridotte in release più

recenti e se sussiste una qualche differenza fra le varie versioni.

Inoltre, potrebbero essere completati alcuni studi già effettuati sul fenomeno (come quelli

descritti nel paragrafo 2.2) stimando l’entità dell’aging imputabile a ciascuna applicazione

Page 124: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

117

in esecuzione sul SO, al netto del contributo dovuto al solo kernel (calcolato con la

procedura presentata).

Si deve tener presente, infine, che l’approccio presentato in questo lavoro può essere esteso

al controllo delle prestazioni di altre tipologie di applicazioni, che consentano di

implementare meccanismi di tracing. In tal senso, Linux è apparso notevolmente

“predisposto” al monitoraggio, poiché offre una serie di strumenti per un reperimento

abbastanza semplice delle informazioni di sistema (file system virtuali, tracepoint, accesso

a tutto il codice del kernel, ecc.).

Page 125: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

118

Bibliografia

[1] Y. Dai, Y. Pan, R. Raje, Advanced Parallel and Distributed Computing, 2006;

[2] A. Silberschatz, P. B. Galvin, G. Gagne, Sistemi operativi, concetti ed esempi, sesta

edizione, 2002;

[3] A. Avižienis, J. C. Laprie, B. Randell, C. Landwehr, Basic Concepts and Taxonomy

of Dependable and Secure Computing, 2004;

[4] J. Gray, Why Do Computers Stop And What Can Be Done About It?, 1985;

[5] M. Grottke, K. S. Trivedi, Fighting bugs: remove, retry, replicate and rejuvenate,

2007;

[6] K. Trivedi, G. Ciardo, B. Dasarathy, M. Grottke, A. Rindos, B. Vashaw, Achieving

and Assuring High Availability, 2008;

[7] Y. Huang, C. Kintala, N. Kolettis e N. D. Fulton, Software Rejuvenation: Analysis,

Module and Applications, 1995;

[8] D. L. Parnas, Software Aging, 1998;

[9] R Reis, Information Technology: Selected Tutorials, 2004;

[10] K. Vaidyanathan, K. S. Trivedi, Extended Classification of Software Faults Based on

Aging, 2001;

[11] T. Dohi, K. Goševa-Popstojanova, K. S. Trivedi, Statistical Non-Parametric

Algorithms to Estimate the Optimal Software Rejuvenation Schedule, 2000;

[12] S. Garg, A. Puliafito, M. Telek, K. S. Trivedi, Analysis of Software Rejuvenation

using Markov Regenerative Stochastic Petri Net, 1995;

Page 126: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

119

[13] K. Vaidyanathan, K. S. Trivedi, A Measurement Based Model for Estimation of

Resource Exhaustion in Operational Software System, 1999;

[14] S. Garg, K. Vaidyanathan, K. S. Trivedi, A Methodology for Detection and

Estimation of Software Aging, 1999;

[15] K. Vaidyanathan, K. S. Trivedi, A Comprehensive Model for Software Rejuvenation,

2005;

[16] V.R. Basili and B.T. Perricone, Software Errors and Complexity: an Empirical

Investigation, 1984;

[17] T. J. Ostrand, E. J. Weyuker, The Distribution of Faults in a Large Industrial

Software System, 2002;

[18] A. Chou, J. Yang, B. Chelf, S. Hallem, D. Engler, An Empirical Study of Operating

System Errors, 2001;

[19] S. Loosemore, R. M. Stallman, R. McGrath, A. Oram, U. Drepper, The GNU C

Library Reference Manual, 2007;

[20] D. P. Bovet, M. Cesati, Understanding the Linux Kernel, 2005;

[21] J. D. Case, M. F., M.L. Schoffstall, C. Davin, M. T. Rose, K. McCloghrie, Simple

Network Management Protocol, 1990;

[22] M. Desnoyers, Using the Linux Kernel Tracepoints, 2009;

[23] R. L. Mason, R. F. Gunst, J. L. Hess, Statistical Design and Analysis of Experiments

With Applications to Engineering and Science, Second Edition, 2003;

[24] R. A. Fisher, The Design of Experiments, 1935;

[25] J. Antony, Design of Experiments for Engineers and Scientists, 2003;

[26] Design of Experiment, dalla rivista on line Orizzonte Scientifico Magazine,

http://www.gmsl.it/magazine/index.asp;

[27] Mark J. Anderson, Shari L. Kraber, Soluzioni per un Doe corretto, 2004;

[28] N. Joukov, A. Traeger, R. Iyer, C. P. Wright, E. Zadok, Operating System Profiling

via Latency Analysis, 2006;

[29] N. Joukov, E. Zadok, Aggregate_stats macros and globals, 2006,

http://ftp.fsl.cs.sunysb.edu/osprof/profilers/POSIX/aggregate_stats.h;

Page 127: ELABORATO DI LAUREA Berniero.pdf · universitÀ degli studi di napoli federico ii facoltÀ di ingegneria corso di laurea specialistica in ingegneria informatica (classe delle lauree

Analisi sperimentale di software aging nel kernel Linux

120

[30] H. B. Mann, Non parametric tests again trend, 1945;

[31] M. G. Kendall, Rank correlation methods, 1962;

[32] J. Shlens, A Tutorial on Principal Component Analysis, 2009;

[33] M. Grottke, K. Vaidyanathan, K. S. Trivedi, Analysis of Software Aging in a Web

Server, 2006.