From: Simone Piccardi Date: Sat, 19 Nov 2011 16:09:33 +0000 (+0000) Subject: Aggiunte note ed un po' di clone. X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=96d16340f5828ce9dbdd023a15978274909deb89 Aggiunte note ed un po' di clone. --- diff --git a/intro.tex b/intro.tex index 2197be8..4289052 100644 --- a/intro.tex +++ b/intro.tex @@ -294,6 +294,11 @@ corrisponde anche alla omonima funzione di libreria; queste costanti sono definite nel file \texttt{sys/syscall.h}, ma si possono anche usare direttamente valori numerici. +% +% TODO:trattare non so se qui o altrove vsyscall e vDSO, vedi +% http://davisdoesdownunder.blogspot.com/2011/02/linux-syscall-vsyscall-and-vdso-oh-my.html +% http://www.win.tue.nl/~aeb/linux/lk/lk-4.html +% \subsection{Un sistema multiutente} \label{sec:intro_multiuser} diff --git a/ipc.tex b/ipc.tex index bd6d126..25f0f30 100644 --- a/ipc.tex +++ b/ipc.tex @@ -3028,6 +3028,12 @@ combinato della memoria condivisa e dei meccanismi di sincronizzazione, per cui alla fine l'uso delle code di messaggi classiche è relativamente poco diffuso. +% TODO: trattare qui, se non ssis trova posto migliore, copy_from_process e +% copy_to_process, introdotte con il kernel 3.2. Vedi +% http://lwn.net/Articles/405346/ e +% http://ozlabs.org/~cyeoh/cma/process_vm_readv.txt + + \subsection{I \textsl{file di lock}} \label{sec:ipc_file_lock} diff --git a/prochand.tex b/prochand.tex index 8120b9f..129e54d 100644 --- a/prochand.tex +++ b/prochand.tex @@ -3297,50 +3297,75 @@ di essa in un secondo tempo. \label{sec:process_clone} La funzione tradizionale con cui creare un nuovo processo in un sistema -Unix-like è, come illustrato in sez.~\ref{sec:proc_fork}, \func{fork}, ma con +Unix-like, come illustrato in sez.~\ref{sec:proc_fork}, è \func{fork}, ma con l'introduzione del supporto del kernel per i \textit{thread} (vedi cap.~\ref{cha:threads}), si è avuta la necessità di una interfaccia che consentisse un maggiore controllo sulla modalità con cui vengono creati nuovi processi, che poi è stata utilizzata anche per fornire ulteriore supporto per -le varie tecnologie di virtualizzazione dei processi (i cosidetti +le tecnologie di virtualizzazione dei processi (i cosidetti \textit{container}). -Per far questo l'interfaccia per la creazione di un nuovo processo è stata -implementata una nuova \textit{system call}, \texttt{sys\_clone}, che consente -di reimplementare anche la tradizionale \func{fork}. La \textit{system call} -richiede due argomenti, \param{flags}, che consente di controllare le modalità -di creazione del nuovo processo e \param{child\_stack}, che deve essere -indicato se si intende creare un \textit{thread} in cui la memoria viene -condivisa fra il processo chiamante ed il nuovo processo creato. L'esecuzione -del programma creato da \param{child\_stack} riprende, come per \func{fork}, -da dopo l'esecuzione della stessa. +Per questo l'interfaccia per la creazione di un nuovo processo è stata +delegata ad una nuova \textit{system call}, \texttt{sys\_clone}, che consente +di reimplementare anche la tradizionale \func{fork}. In realtà in questo caso +più che di nuovi processi si può parlare della creazioni di nuovi +``\textit{task}'' del kernel che possono assumere la veste sia di un processo +vero e proprio come quelli trattati finora, che di un \textit{thread}, come +quelli che vedremo in sez.~\ref{sec:linux_thread}, in cui la memoria viene +condivisa fra il processo chiamante ed il nuovo processo creato. Per evitare +confusione fra \textit{thread} e processi ordinari, abbiamo deciso di usare la +nomenclatura \textit{task} per indicare la unità di esecuzione generica messa +a disposizione del kernel che \texttt{sys\_clone} permette di creare. + +La \textit{system call} richiede soltanto due argomenti: il +primo, \param{flags}, consente di controllare le modalità di creazione del +nuovo \textit{task}, il secondo, \param{child\_stack}, imposta l'indirizzo +dello \itindex{stack} \textit{stack} per il nuovo \textit{task}, e deve essere +indicato quando si intende creare un \textit{thread}. L'esecuzione del +programma creato da \param{child\_stack} riprende, come per \func{fork}, da +dopo l'esecuzione della stessa. La necessità di avere uno \itindex{stack} \textit{stack} alternativo c'è solo quando si intende creare un \textit{thread}, in tal caso infatti il nuovo -processo vede esattamente la stessa memoria del processo chiamante, e nella -sua esecuzione andrebbe a scrivere sullo \textit{stack} usato anche da questi, -il che comporterebbe immediatamente la presenza di \itindex{race~condition} -\textit{race conditions} all'esecuzione di una funzione da parte di entrambi +\textit{task} vede esattamente la stessa memoria del \textit{task} +``\textsl{padre}'',\footnote{in questo caso per padre si intende semplicemente + il \textit{task} che ha eseguito \texttt{sys\_clone} rispetto al + \textit{task} da essa creato, senza nessuna delle implicazioni che il + concetto ha per i processi.} e nella sua esecuzione alla prima chiamata di +una funzione andrebbe a scrivere sullo \textit{stack} usato anche dal padre (si ricordi quanto visto in sez.~\ref{sec:proc_mem_layout} riguardo all'uso -dello \textit{stack}). - -Per evitare questo è allora necessario che il chiamante allochi -preventivamente un'area di memoria (in genere lo si fa con una \func{malloc}) -che la funzione imposterà come \textit{stack} del nuovo processo, avendo -ovviamente cura di non utilizzarla direttamente. Si tenga presente inoltre che -in molte architetture lo \textit{stack} cresce verso il basso, pertanto in tal -caso non si dovrà specificare per \param{child\_stack} il puntatore restituito -da \func{malloc}, ma un puntatore alla fine del buffer con essa allocato. - -Dato che tutto ciò serve solo per i \textit{thread} che condividono la +dello \textit{stack}). + +Per evitare di doversi garantire contro la evidente possibilità di +\itindex{race~condition} \textit{race conditions} che questa situazione +comporta è necessario che il chiamante allochi preventivamente un'area di +memoria (in genere lo si fa con una \func{malloc}) che la funzione imposterà +come \textit{stack} del nuovo processo, avendo ovviamente cura di non +utilizzarla direttamente. In questo modo i due \textit{task} avranno degli +\textit{stack} indipendenti e non si dovranno affrontare problematiche di +\itindex{race~condition} \textit{race conditions}. Si tenga presente inoltre +che in molte architetture lo \textit{stack} cresce verso il basso, pertanto in +tal caso non si dovrà specificare per \param{child\_stack} il puntatore +restituito da \func{malloc}, ma un puntatore alla fine del buffer con essa +allocato. + +Dato che tutto ciò è necessario solo per i \textit{thread} che condividono la memoria, la \textit{system call}, a differenza della funzione di libreria che -vedremo a breve, consente anche di passare il valore \val{NULL} -per \param{child\_stack}, nel qual caso si applicherà la semantica del -\itindex{copy-on-write} \textit{copy on write} illustrata in -sez.~\ref{sec:proc_fork}, le pagine dello \textit{stack} verranno -automaticamente copiate come le altre e il nuovo processo avrà un suo -\textit{stack}. +vedremo a breve, consente anche di passare per \param{child\_stack} il valore +\val{NULL}, che non imposta un nuovo \textit{stack}. Se infatti si crea un +processo, questo ottiene un suo nuovo spazio degli indirizzi,\footnote{è + sottinteso cioè che non si stia usando il flag \const{CLONE\_VM}.} ed in +questo caso si applica la semantica del \itindex{copy-on-write} \textit{copy + on write} illustrata in sez.~\ref{sec:proc_fork}, per cui le pagine dello +\textit{stack} verranno automaticamente copiate come le altre e il nuovo +processo avrà un suo \textit{stack} totalmente indipendente da quello del +padre. + +Dato che l'uso principale della nuova \textit{system call} è quello relativo +alla creazione dei \textit{thread}, le \acr{glibc} definiscono una funzione di +libreria +\funcd{clone} \subsection{La funzione \func{prctl}} @@ -3353,7 +3378,7 @@ la cui gestione è stata predisposta una apposita \textit{system call} che fornisce una interfaccia generica per tutte le operazioni specialistiche. La funzione è \funcd{prctl} ed il suo prototipo è:\footnote{la funzione non è standardizzata ed è specifica di Linux, anche se ne esiste una analoga in - IRIX, è stata introdotta con il kernel 2.1.57.} + IRIX; è stata introdotta con il kernel 2.1.57.} \begin{functions} \headdecl{sys/prctl.h}