...Un piccolo script per l'installazione di LAMP, LINUX APACHE MYSQL PHP, la piattaforma di sviluppo di applicazioni web.
il codice e' questo ma si puo' scaricare da
http://hotfile.com/dl/34333712/39edf98/lampinstall.bash.html
#~/bin/bash
salute() {
echo
echo " hi , wellcome to the Lamp installation Script " ;
echo
}
controlling_root() {
echo ...
if [ $UID == 0 ]
then
echo "ok" ;
else
echo "...NOP ! Bye, see ya when the root user comes back" ;
echo "\(you have to be root\)";
exit;
fi
}
sleep 1
clear
salute #function
sleep 1
echo "first thing...updating" ;
echo " wait wait...are you root? ( controlling )" ;
controlling_root #function
apt-get update && upgrade
apt-get install mysql-server mysql-client
echo "mysql installed, now, we (me and you) provide to install apache2" ;
sleep 2
apt-get install apache2 apache2-doc
sleep 2
echo "apache installed, now php stuff must be installed: ";
#or apt-get install php5 php5-mysql libapache2-mod-php5
# or apt-get install perl libapache2-mod-perl2
apt-get install python libapache2-mod-python
##### ok, 2nd step, configuring apache
echo
echo
echo "ok, now apache2 must be configured," ;
sleep 1
echo "the configuration file is: /etc/apache2/apache2.conf" ;
sleep 1
echo " now I open the file, and I will add a line: " ;
echo "file: /var/www/apache2-default/test.php" ;
echo "line: " ;
sleep 1
echo "" > /var/www/test.php ;
echo "ok...done!" ;
sleep 3
echo "now for easy configuration, phpmyadmin must be installed" ;
sleep 3
apt-get install phpmyadmin
echo "done!" ;
sleep 2
echo " now adding the line"
echo " Include /etc/phpmyadmin/apache.conf"
echo "in /etc/apache2/apache2.conf";
echo "Include /etc/phpmyadmin/apache.conf" >> /etc/apache2.apache2.conf
sleep4
echo "..and restarting apache "
sleep 1
/etc/init.d/apache2 restart
sleep 2; clear ;
sleep 3
clear
sleep1
echo "now..apache2 configuration , libraries and restarting"
sleep 1
clear
echo "installing libapache2-mod-php5 php5-cli php5-common php5-cgi"
apt-get install libapache2-mod-php5 php5-cli php5-common php5-cgi
sleep 1
clear
echo "...and restarting apache2"
/etc/init.d/apache2 restart
venerdì 12 marzo 2010
venerdì 5 marzo 2010
Memoria Virtuale
Memoria Virtuale.
Le tecniche di gestione della memoria prevedono la suddivisione degli spazi fisici e logici dei processi per conservarli in memoria centrale in modo da migliorare efficientemente la multiprogrammazione lavorando pero' sugli spazi logici, e' possibile evitare di dover tenere un processo completamente in memoria e trarne diversi vantaggi.
Infatti e' possibile eseguire un processo che non e' caricato completamente poiche' il codice potrebbe contenere riferimenti a routines di gestione di errori che verrebbero richiamate di rado, oppure verrebbero utilizzate variabili che occupano spazi inutilizzati, come array di dimensione esagerate rispetto all'utilizzo necessario.
I vantaggi che riguardano un caricamento parziale di un processo sono stimabili in termini di spazio, poiche' meno frame fisici sono utilizzati, quindi occupati. Un secondo vantaggio e' il grado di multiprogrammazione, possono essere tenuti piu' programmi in memoria visto che occuerebbero meno, ed infine il sistema sarebbe piu' veloce, poiche' ci sarebbero meno operazioni di i/o per caricare un programma utente (meno pagine logiche!).
Nella tecnica di memoria virtuale lo swapping, la tecnica che prevede di caricare processi in memoria centrale dalla memoria secondaria e viceversa, viene sostituito con il lazy swapping, che carica solo alcune pagine logiche del processo.
Il pager e' il modulo che affronta questo tipo di lavoro.
Un processo, per come e' strutturato, puo' infatti sugerire al pager quali pagine caricare e di quali routine, librerie e funzioni ha bisogno per essere eseguito.
Questo puo' essere ben compreso attraverso lo spazio degli indirizzi, un'espressione che fa riferimento al modo di memorizzazione logica, quindi apparentemente contigua, di un processo.
Parte da un determinato indirizzo, e presenta un segmento dedicato al codice, uno dedicato ai dati, poi heap e stack, ma tra questi ultimi c'e' uno spazio che permette all'heap e allo stack di crescere.
Questo spazio libero necessita di pagine fisiche, quindi frames, solo se l'heap o lo stack crescono.
La funzione del buco e' sia di lasciare spazio ai segmenti adiacenti (come gia' detto heap e stack) ma anche di permettere collegamenti dinamici a librerie che il processo potrebbe richiedere all'istante.
Quindi e' un punto di forza per la condivisione della memoria, sia per le librerie che per l'ipc.
Il pager carica solo le pagine necessarie.
Per identificarle, nella page table di ogni processo queste sono segnate come "valide", ossia che appartengono allo spazio di indirizzi logici e sono presenti in memoria.
Un processo nell'esecuzione richiede accesso alle pagine, se il riferimento in memoria non e' valido il processo termina, altrimenti la pagina deve essere caricata.
Un accesso a pagina mancante si chiama PAGE FAULT.
Quindi si individua un frame libero, si aggiornano le tabelle e continua l'esecuzione.
Cosa accade se non c'e' un frame libero? In questo caso si parla di sostituzione, ossia si scegli un frame vittima, si scrive la pagina richiesta nel frame, si modificano le tabelle delle pagine e si prosegue con l'esecuzione.
Quindi si hanno due cambiamenti di pagine, nel frame e nella memoria.
Si puo' evitare associando un bit (dirty bit) ad un apagina, che segnala che quella pagina e' stata modificata, quindi deve essere scritta sul disco.
Gli algoritmi di sostituzione delle pagine si basano sulla frequenza di page fault. Si studiano in base a successioni di riferimenti che si ottengono attraverso successioni di numeri casuali.
Un primo algoritmo e' affrontare la successione calcolando il numero di page fault tramite la sostituzione di pagine in modo FIFO, un secondo algoritmo e' la sostituzione ottimale, per il quale si sostituisce la pagina mancante con quella che non si iusera' per il periodo piu' lungo.
Ma non e' realizzabile, poiche' dovrebbe essere noto l'utilizzo futuro delle pagine.
L'LRU invece, usa sostituire la pagina con quella che non e' stata usata per il tempo piu' lungo.
Sono poche le architetture che sfruttano un algoritmo di sostituzione LRU, ma puo' essere approssimato, ad esempio un algoritmo FIFO puo' essere aiutato da un bit di riferimento nel seguente modo:
inizialmente tutte le pagine hanno un bit impostato a zero, quando il sistema fa riferimenteo ad una pagina imposta il bit a 1, in modo tale che in ogni istante si conoscono le pagine utilizzate. Tuttavia non si puo' conoscere l'ordine in cui sono state utilizzate.
Le tecniche di gestione della memoria prevedono la suddivisione degli spazi fisici e logici dei processi per conservarli in memoria centrale in modo da migliorare efficientemente la multiprogrammazione lavorando pero' sugli spazi logici, e' possibile evitare di dover tenere un processo completamente in memoria e trarne diversi vantaggi.
Infatti e' possibile eseguire un processo che non e' caricato completamente poiche' il codice potrebbe contenere riferimenti a routines di gestione di errori che verrebbero richiamate di rado, oppure verrebbero utilizzate variabili che occupano spazi inutilizzati, come array di dimensione esagerate rispetto all'utilizzo necessario.
I vantaggi che riguardano un caricamento parziale di un processo sono stimabili in termini di spazio, poiche' meno frame fisici sono utilizzati, quindi occupati. Un secondo vantaggio e' il grado di multiprogrammazione, possono essere tenuti piu' programmi in memoria visto che occuerebbero meno, ed infine il sistema sarebbe piu' veloce, poiche' ci sarebbero meno operazioni di i/o per caricare un programma utente (meno pagine logiche!).
Nella tecnica di memoria virtuale lo swapping, la tecnica che prevede di caricare processi in memoria centrale dalla memoria secondaria e viceversa, viene sostituito con il lazy swapping, che carica solo alcune pagine logiche del processo.
Il pager e' il modulo che affronta questo tipo di lavoro.
Un processo, per come e' strutturato, puo' infatti sugerire al pager quali pagine caricare e di quali routine, librerie e funzioni ha bisogno per essere eseguito.
Questo puo' essere ben compreso attraverso lo spazio degli indirizzi, un'espressione che fa riferimento al modo di memorizzazione logica, quindi apparentemente contigua, di un processo.
Parte da un determinato indirizzo, e presenta un segmento dedicato al codice, uno dedicato ai dati, poi heap e stack, ma tra questi ultimi c'e' uno spazio che permette all'heap e allo stack di crescere.
Questo spazio libero necessita di pagine fisiche, quindi frames, solo se l'heap o lo stack crescono.
La funzione del buco e' sia di lasciare spazio ai segmenti adiacenti (come gia' detto heap e stack) ma anche di permettere collegamenti dinamici a librerie che il processo potrebbe richiedere all'istante.
Quindi e' un punto di forza per la condivisione della memoria, sia per le librerie che per l'ipc.
Il pager carica solo le pagine necessarie.
Per identificarle, nella page table di ogni processo queste sono segnate come "valide", ossia che appartengono allo spazio di indirizzi logici e sono presenti in memoria.
Un processo nell'esecuzione richiede accesso alle pagine, se il riferimento in memoria non e' valido il processo termina, altrimenti la pagina deve essere caricata.
Un accesso a pagina mancante si chiama PAGE FAULT.
Quindi si individua un frame libero, si aggiornano le tabelle e continua l'esecuzione.
Cosa accade se non c'e' un frame libero? In questo caso si parla di sostituzione, ossia si scegli un frame vittima, si scrive la pagina richiesta nel frame, si modificano le tabelle delle pagine e si prosegue con l'esecuzione.
Quindi si hanno due cambiamenti di pagine, nel frame e nella memoria.
Si puo' evitare associando un bit (dirty bit) ad un apagina, che segnala che quella pagina e' stata modificata, quindi deve essere scritta sul disco.
Gli algoritmi di sostituzione delle pagine si basano sulla frequenza di page fault. Si studiano in base a successioni di riferimenti che si ottengono attraverso successioni di numeri casuali.
Un primo algoritmo e' affrontare la successione calcolando il numero di page fault tramite la sostituzione di pagine in modo FIFO, un secondo algoritmo e' la sostituzione ottimale, per il quale si sostituisce la pagina mancante con quella che non si iusera' per il periodo piu' lungo.
Ma non e' realizzabile, poiche' dovrebbe essere noto l'utilizzo futuro delle pagine.
L'LRU invece, usa sostituire la pagina con quella che non e' stata usata per il tempo piu' lungo.
Sono poche le architetture che sfruttano un algoritmo di sostituzione LRU, ma puo' essere approssimato, ad esempio un algoritmo FIFO puo' essere aiutato da un bit di riferimento nel seguente modo:
inizialmente tutte le pagine hanno un bit impostato a zero, quando il sistema fa riferimenteo ad una pagina imposta il bit a 1, in modo tale che in ogni istante si conoscono le pagine utilizzate. Tuttavia non si puo' conoscere l'ordine in cui sono state utilizzate.
Gestione della memoria
Memoria Centrale.
Visto che l'obiettivo di avere un sistema efficiente ha portato alla multiprogrammazione, ossia l'alternarsi di piu' processi in cpu, la memoria centrale dovra' ospitare diversi processi, e siccome non e' grande abbastanza da contenerli tutti, dovra' essere gestita dal sistema operativo nel modo piu' efficiente possibile.
Il ciclo di cpu prevede 3 istruzioni principali: fetch decode execute, prevede la lettura e scrittura oltre all'esecuzione vera e propria, da e su dispositivi di memorizzazione.
Questi possono essere accessibili direttamente dal processore.
Alla memoria centrale si accede tramite bus.
La questione di velocita' d'accesso e' coperta dalla memoria cache, un dispositivo di memorizzazione che sfrutta principi di localita' e temportali per cui si controlla se un'istruzione e' presente in cache o bisogna andare a prelevarla in memoria, ma un fattore altrettanto importante oltre alla cache e' la velocita' di protezione.
La memoria e' protetta grazie al meccanismo di protezione hardware offerto da due registri base e limite.
Quando un processo richiede accesso ad un'area di memoria si controllano gli indirizzi attraverso questi due registri: il registro base contiene il piu' piccolo indirizzo a cui puo' accerdere, il registro limite contiene l'inervallo di indirizzi a cui il processo puo' accedere.
Un tentativo di accesso a intervalli di memoria sbagliata comporta una trap.
Quando un programma utente viene scelto per l'esecuzione puo' venire caricato in memoria passando per vari stadi in cui gli indirizzi sono rappresentati in modo diverso.
Infatti gli indirizzi del codice sorgente sono simbolici, un compilatore li rende rilocabili ed un loader li fa corrispondere ad indirizzi assoluti.
I metodi di associazione degli indirizzi nella fasi di compilazione e caricamento producono indirizzi logici e fisici identici, mentre nella fase d'esecuzione l'associazione degli indirizzi e' compito dell'MMU.
L'MMU e' un dispositivo che contiene un registro di rilocazione che ha un valore a cui deve essere sommato l'indirizzo logico per ottenere l'indirizzo fisico.
La separazioned degi indirizzi logici e fisici e' un primo passo verso tecniche di memorizzazione molto efficienti.
In primo luogo e' possibile avere un caricamento dinamico di procedure, che occupano la memoria solo quando vengono chiamate, o di librerie, che ancor meglio vengono linkate, in modo che durante l'esecuzione di un programma il riferimento fa si che venga ricercata la libreria linkata e se non e' presente viene caricata in memoria. Questo meccanismo e' molto utile per l'aggiornamento delle librerie.
Il caricamento in memoria delle immagini dei processi e' detto swapping, o avvicendamento, e' l'atto di caricare dalla memoria ausiliaria in memoria centrale i processi che richiede la cpu.
La coda dei processi pronti conserva puntatori alle immagini dei processi (in memoria secondaria).
La gestione della memoria segue un percorso siffatto: inizialmente la cosa piu' importante e' la rilocazione, ossia voler caricare processi in memoria, e scaricarli, ma dividendo lo spazio degli indirizzi logici da quello degli indirizzi fisici, in modo tale che siamo capaci uno, di swappare i processi per rendere efficiente l'utilizzo del processore, e due di rilocare i processi caricati di nuovo in memoria in altre porzioni.
Dopo il primo aspetto della rilocazione vi e' quello della protezione, quindi la stessa separazione degli indirizzi pone dei limiti di permessi che i processi sono costretti a seguire attraverso registri di rilocazione.
Si parla di associazione dinamica degli indirizzi in runtime (MMU).
Ma la principale funzione della gestione della memoria e' quella di organizzarla per accogliere piu' processi.
Un primo approccio e' quello di suddividere la memoria ( spazio contiguo di indirizzi) in partizioni di dimensione fissa.
Il partizionamento fisso e' una tecnica per la quale vengono scelti i processi da una coda d'ingresso per essere inseriti in memoria.
Sono 3 le strategie di posizionamento : best fit, il processo viene messo nel buco di memoria piu' adatto, first fit, il processo occupera' la posizione di memoria che lo contiene che incontra per prima, worst fit: il processo sara' accolto dalla partizione piu' comoda.
Vi e' uno spreco enorme di memoria, che genera due problematiche gravi: la frammentazione interna si ha all'interno della partizione fissa che accogli un processo quindi l'algoritmo di partizionamento worst fit e' quello che causa maggior danno in termini di framentazinoe interna.
La frammentazione esterna e' data dal fatto che non tutte le partizioni vengono occupate.
La soluzione e' in primo luogo il partizionamento dinamico, in cui le partizioni occupate possono essere in un certo modo accorpate per cui creano uno spazio partizionabile ricorsivamente.
Comunque non risolverebbe la frammentazione esterna.
Per evitare questi due problemi bisogna permettere che lo spazio di memoria non sia contiguo.
Questo vuol dire allocare un processo in segmenti di memoria sparsi, non adiacenti.
Per farlo oltre a dividere la memoria si dovra' dividere lo spazio logico, per poi avere dei riferimenti.
La memoria centrale si divide in frames, il processo, o meglio la memoria logica che lo rappresenta, in pagine.
Le pagine e i frame hanno uguale dimensione, che e' data dall'architettura della macchina, ed e' compresa tra 512 byte e 16 Mb. Ed e' una potenza di 2, perche' se lo spazio di indirizzi logici e' grande 2 alla m e una pagina e' 2 alla n, m-n sono il numero delle pagine ed n e' l'offset.
L'architettura di paginazione funziona cosi:
la cpu genera un indirizzo logico, che e' diviso in due, un numero di pagina, rappresentato da m-n bit, il numero di pagina punta alla page table, un riferimento ai frame corrispondenti, presente in ogni processo, o meglio ogni pcb ha un puntatore ad una struttura dati che rappresenta la tabella delle pagine.
Una volta individuato il numero di frame si somma l'offset per ottere l'indirizzo del frame fisico in memoria centrale.
Ma com'e' realizzata una page table?
Si puo' implementare attraverso una serie di registri che la cpu carica ogni volta dopo che il pcb espone il puntatore che indica i valori che deve avere, ma la tabella delle pagine e' molto grande, quindi non sarebbe contenuta in registri. Un metodo alternativo e' utilizzare un solo registro, in cui viene caricata la tabella delle pagine del processo in esecuzione, Page Table Base Register, quindi occorre accedere al PTBR, e poi al frame per ottenere un numero di frame...e due accessi alla memoria non rendono la gestione molto efficiente.
Quindi si utilizza il TLB: Translation Look Aside Buffer, che funziona come una cache, ossia mantiene alcuni numeri di frame per cui la parte dell'indirizzo logico relativa al numero di pagina indica un campo del TLB, e se vi e' presente il numero di pagina si evita l'accesso in memoria, altrimenti si accede alla page table.
Logicamente ci vuole una protezione interna alla paginazione, ma e' facile aggiungere nella struttura dati della page table un campo che indica se il riferimento e' valido o meno, ossia se il bit di una pagina e' impostato a valido vuol dire che quella pagina risiede nello spazio logico del processo.
La paginazione consente di condividere spazi di memoria: se un codice e' rientrante o puro, questo non viene modificato durante l'esecuzione, quindi puo' risiedere in memoria senza copie ed essere utilizzato da piu' preocessi.
Iscriviti a:
Post (Atom)
How to deploy Podman images to OpenShift Container Platform (CRC on localhost)
I have a microservice on localhost and I want to deploy its Podman image on OCP, which I am running using CRC on localhost. 1. Get the...
-
My intent is to configure SSO on Keycloak and Liferay. I have createad a docker-compose environment with Keycloak: #####################...
-
Precondizione: La precondizione di un metodo e' una condizione che deve essere verificata prima che quel metodo sia invocato. Le preco...