From f8d990a1b2a184dba66301ae20d1f7e8f300c139 Mon Sep 17 00:00:00 2001 From: Simone Piccardi Date: Sun, 20 Nov 2011 08:34:34 +0000 Subject: [PATCH] Ancora clone --- prochand.tex | 105 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 71 insertions(+), 34 deletions(-) diff --git a/prochand.tex b/prochand.tex index 129e54d..af296b6 100644 --- a/prochand.tex +++ b/prochand.tex @@ -3301,53 +3301,60 @@ 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 tecnologie di virtualizzazione dei processi (i cosidetti -\textit{container}). +processi, che poi è stata utilizzata anche per fornire supporto per le +tecnologie di virtualizzazione dei processi (i cosiddetti \textit{container}). 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 +delegata ad una nuova \textit{system call}, \func{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 +classico 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. +Oltre a questo la funzione consente, ad uso delle nuove funzionalità di +virtualizzazione dei processi, di creare nuovi \textit{namespace} per una +serie di proprietà generali dei processi (come l'elenco dei PID, l'albero dei +file, dei \textit{mount point}, della rete, ecc.), che consentono di creare +gruppi di processi che vivono in una sorta di spazio separato dagli altri, che +costituisce poi quello che viene chiamato un \textit{container}. + 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 +programma creato da \func{sys\_clone} 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 \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}). + il \textit{task} che ha eseguito \func{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 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. +\itindex{race~condition} \textit{race condition} che questa situazione +comporta (vedi sez.~\ref{sec:proc_race_cond} per una spiegazione della +problematica) è necessario che il chiamante allochi preventivamente un'area di +memoria. In genere lo si fa con una \func{malloc} che allochi un buffer che +la funzione imposterà come \textit{stack} del nuovo processo, avendo +ovviamente cura di non utilizzarlo direttamente nel processo chiamante. In +questo modo i due \textit{task} avranno degli \textit{stack} indipendenti e +non si dovranno affrontare problematiche di \itindex{race~condition} +\textit{race condition}. Si tenga presente inoltre che in molte architetture +di processore 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 da 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 @@ -3363,9 +3370,39 @@ 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 +libreria con una sintassi diversa, orientata a questo scopo, e la +\textit{system call} resta accessibile solo se invocata esplicitamente come +visto in sez.~\ref{sec:intro_syscall}.\footnote{ed inoltre per questa + \textit{system call} non è disponibile la chiamata veloce con + \texttt{vsyscall}.} La funzione di libreria si chiama semplicemente +\funcd{clone} ed il suo prototipo è: +\begin{functions} + \headdecl{sys/sched.h} + + \funcdecl{int clone(int (*fn)(void *), void *child\_stack, int + flags, void *arg, ... \\ + /* pid\_t *ptid, struct user\_desc *tls, pid\_t *ctid */)} + + Crea un nuovo processo o \textit{thread} eseguendo la funzione \param{fn}. + + \bodydesc{La funzione ritorna al chiamante il \textit{Thread ID} assegnato + al nuovo processo in caso di successo e $-1$ in caso di errore, nel qual + caso \var{errno} può assumere i valori: + \begin{errlist} + \item[\errcode{EAGAIN}] sono già in esecuzione troppi processi. + \item[\errcode{EINVAL}] si è usata una combinazione non valida di flag o + un valore nullo per \param{child\_stack}. + \item[\errcode{ENOMEM}] non c'è memoria sufficiente per creare una nuova + \struct{task\_struct} o per copiare le parti del contesto del chiamante + necessarie al nuovo \textit{task}. + \item[\errcode{EPERM}] non si hanno i privilegi di amministratore + richiesti dai flag indicati. + \end{errlist} + } +\end{functions} + + -\funcd{clone} \subsection{La funzione \func{prctl}} @@ -3874,11 +3911,11 @@ varie funzioni di libreria, che sono identificate aggiungendo il suffisso % LocalWords: completely fair compat uniform CFQ queuing elevator dev cfq RT % LocalWords: documentation block syscall ioprio IPRIO CLASS class best effort % LocalWords: refresh semop dnotify MADV DONTFORK prctl WCLONE SIGCHL WALL big -% LocalWords: WNOTHREAD DUMPABLE KEEPCAPS IRIX CAPBSET endianess endian -% LocalWords: little PPC PowerPC FPEMU NOPRINT SIGFPE FPEXC point FP SW +% LocalWords: WNOTHREAD DUMPABLE KEEPCAPS IRIX CAPBSET endianess endian flags +% LocalWords: little PPC PowerPC FPEMU NOPRINT SIGFPE FPEXC point FP SW malloc % LocalWords: exception EXC ENABLE OVF overflow UND underflow RES INV DISABLED -% LocalWords: NONRECOV ASYNC KEEP securebits NAME NUL PDEATHSIG SECCOMP -% LocalWords: secure computing sigreturn TIMING STATISTICAL TSC MCE +% LocalWords: NONRECOV ASYNC KEEP securebits NAME NUL PDEATHSIG SECCOMP VM +% LocalWords: secure computing sigreturn TIMING STATISTICAL TSC MCE conditions % LocalWords: timestamp Stamp SIGSEGV UNALIGN SIGBUS MCEERR AO failure early %%% Local Variables: -- 2.30.2