flock (2) contro fcntl (2) su un NFS


19

La documentazione di Perl 5.x afferma che la sua implementazione di flock (..) utilizzerà una delle seguenti chiamate native, a partire da 1 e funzionando verso 3 se non disponibile:

  1. flock (2)
  2. fcntl (2)
  3. lockf (3)

Va bene. Tuttavia, potresti aver notato il loro disclaimer che flock (2) non dovrebbe essere usato su un NFS. Il documento suggerisce di usare un flag -Ud_flock per forzare Perl a usare flock (2). La pagina man di flock (2) (su Redhat) afferma un disclaimer simile sui problemi di NFS.

La mia domanda è: perché!?!? Non riesco a trovare un articolo approfondito o una spiegazione del perché il gregge (2) non è sicuro su un NFS.

Ho scritto diversi script di test in C e Perl, sia su Redhat (dove viene utilizzato flock (2)) sia su Solaris (dove viene utilizzato fcntl (2)). Ho eseguito strace / truss per assicurarmi che Perl stesse usando effettivamente flock (2) e fcntl (2) rispettivamente. Non ho potuto replicare eventuali problemi in cui un lucchetto non veniva onorato! Cosa dà ??

Risposte:


3

Lennart Poettering ha recentemente scavato nel comportamento di blocco del filesystem linux, che non dipinge un quadro particolarmente roseo per il blocco su NFS (in particolare il follow-up a cui si collega in fondo al post).

http://0pointer.de/blog/projects/locking.html


1
Questo è il tipo esatto di informazioni che stavo cercando. Grazie! Dopo diverse settimane di indagine, ho trovato una risoluzione molto simile, ma è bello leggere un articolo che conferma i miei sospetti (e suggerisce altri). Anche il link dai commenti di quella pagina era un buon riferimento e un buon articolo su POSIX e la sua storia): samba.org/samba/news/articles/low_point/tale_two_stds_os2.html
Jmoney38

15

Sono abbastanza sicuro che stai osservando le preoccupazioni ereditate. Ricordiamo che il manuale Perl5 è stato rilasciato nel 1994 e che era solo una modifica del manuale Perl4 del 1991. A quei tempi probabilmente si poteva dire del spesso chiamato Nightmare File System che "non è quanto l'orso balli bene che stupisce, ma che balla affatto ".

NFS2 nell'epoca del 1991 stava lentamente uscendo da Sun verso altre piattaforme ed era relativamente rozzo. Il modello di sicurezza era essenzialmente inesistente (il root su una macchina client poteva leggere l'intero contenuto di un mount NFS) e il blocco - tramite nfs.lockd - era questo lato dell'esperimento. Sarebbe stato sciocco aspettarsi che la semantica del gregge funzionasse correttamente se mai tra due diverse implementazioni presumibilmente interoperabili. Coax era il PHY Ethernet dominante al momento che molti utenti della rete non hanno mai avuto il dispiacere di usare (cosa vuoi dire che hai dimenticato di mettere su il resistore di terminazione da 50𝛀?) Se questo ti dà una migliore presa sullo stato delle intranet allora.

Larry Wall e l'equipaggio avevano tutte le ragioni per fare ipotesi pessimistiche sulla correttezza delle serrature NFS in quel momento, e questo è il tipo di programmazione difensiva che i futuri fantini del codice detestano rimuovere perché è così difficile dimostrare l'assenza di un difetto rimuovere il vecchio codice che viene reintrodotto nell'interoperabilità con un sistema legacy di cui non hai mai nemmeno sentito parlare.

Da allora, NFS è migliorato considerevolmente e lockd è migrato in tempo a una funzionalità del kernel Linux 2.6. Per una raccolta di sistemi 2003+, il blocco dei file NFS può essere probabilmente attendibile, specialmente se testato bene all'interno dell'applicazione su molte piattaforme su cui potrebbe essere in esecuzione.

Tutto quanto sopra è stato paralizzato dalla memoria e probabilmente potrebbe essere comprovato dalla ricerca (ad esempio http://nfs.sourceforge.net/ ) ma la prova - come si dice - è nel blocco e se non l'hai testata , si presume rotto.


Questa è un'ottima analisi. In effetti, sono giunto alla stessa conclusione finora. Ho letto di nuovo la pagina nfs sourceforge dopo aver pubblicato quel link e ho finalmente trovato quello che cercavo! Ecco un'analisi approfondita direttamente dalla bocca del cavallo!
Jmoney38,

2
oops, premo invio ... vai a nfs.sourceforge.net , la sezione D10 verso il basso discute questo problema in dettaglio.
Jmoney38,

3

Un altro, direttamente dalle FAQ su Linux-NFS: nfs.sf.net

Sto cercando di utilizzare i blocchi flock () / BSD per bloccare i file utilizzati su più client, ma i file vengono danneggiati. Come mai? I blocchi A. flock () / BSD agiscono solo localmente sui client NFS Linux precedenti alla 2.6.12. Utilizzare i blocchi fcntl () / POSIX per assicurarsi che i blocchi dei file siano visibili ad altri client.

Ecco alcuni modi per serializzare l'accesso a un file NFS.

Utilizzare l'API di blocco fcntl () / POSIX. Questo tipo di blocco fornisce il blocco dell'intervallo di byte su più client tramite il protocollo NLM o tramite NFSv4. Utilizzare un file di blocco separato e creare collegamenti reali ad esso. Vedi la descrizione nella sezione O_EXCL della pagina man creat (2). Vale la pena notare che fino ai primi 2.6 kernel, le creazioni O_EXCL non erano atomiche sui client NFS Linux. Non utilizzare O_EXCL crea e prevede comportamenti atomici tra più client NFS a meno che non stia eseguendo un kernel più recente della 2.6.5.

È un problema noto che Perl utilizza il blocco flock () / BSD per impostazione predefinita. Ciò può interrompere i programmi portati da altri sistemi operativi, come Solaris, che prevedono che i blocchi flock / BSD funzionino come i blocchi POSIX.

Su Linux, l'utilizzo del blocco dei file anziché di un collegamento reale ha l'ulteriore vantaggio di controllare la cache del client con il server. Quando viene acquisito un blocco file, il client svuota la cache della pagina per quel file in modo che eventuali letture successive ottengano nuovi dati dal server. Quando viene rilasciato un blocco file, tutte le modifiche al file su quel client vengono rinviate al server prima del rilascio del blocco in modo che altri client in attesa di bloccare quel file possano vedere le modifiche.

Il client NFS in 2.6.12 fornisce supporto per i blocchi flock () / BSD sui file NFS emulando i blocchi in stile BSD in termini di blocchi dell'intervallo di byte POSIX. Altri client NFS che usano lo stesso meccanismo di emulazione o che usano i blocchi fcntl () / POSIX, vedranno quindi gli stessi blocchi che vede il client NFS Linux.

Sui file system Linux locali, i blocchi POSIX e i blocchi BSD sono invisibili l'uno all'altro. Pertanto, a causa di questa emulazione, le applicazioni in esecuzione su un server NFS Linux vedranno comunque i file bloccati dai client NFS come bloccati con un blocco fcntl () / POSIX, indipendentemente dal fatto che l'applicazione sul client stia usando uno stile BSD o POSIX- blocco di stile. Se l'applicazione server utilizza i blocchi BSD flock (), non vedrà i blocchi utilizzati dai client NFS.


Quindi due client NFS che eseguono il kernel 3.13. * Vedono l'un l'altro i flock () s?
reinierpost,

Se sto capendo correttamente, la risposta è no. A meno che non mi sia sfuggito qualcosa, flocknon lo sia, non lo faccia e non si bloccherà su tutti i supporti nfs.
Daniel Farrell,

Lo fa, almeno su NFS4.
rjh

3

Questo non è aggiornato ora. NFS4 supporta il blocco all'interno del protocollo (non è richiesto alcun demone lockd o meccanismo di callback RPC) e il flock()metodo Perl funziona bene - lo stiamo usando in produzione.

Versioni molto vecchie del kernel implementate flock(la syscall) come no-op su NFS, e altre cose come il blocco dell'intervallo di byte non erano adeguatamente supportate. Ecco da dove proviene l'isteria.


Grazie mille per il suggerimento. Il montaggio con NFS4 ha risolto il mio problema. Seguito access.redhat.com/documentation/en-us/red_hat_enterprise_linux/… per ottenere correttamente la configurazione di fstab.
Maraspin,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.