From: Matteo Ianeselli <xxxxxxxxxxx@xxxxxxxxxx> Date: Sat, 25 May 2002 21:38:49 +0200 To: linuxtrent@freelists.org Subject: [Linuxtrent] Re: Lock di un file
Daniele Nicolodi writes:
> Quali sono le soluzioni su un sistema unix per fare il lock di un file ??
Fondamentalmente hai due sistemi:
-
Advisory lock tramite link (simbolici o non)
E` “advisory” nel senso che e` compito dei processi comportarsi “per bene” e controllare che il lock in questione non ce l’abbiano altri.
From: Matteo Ianeselli <xxxxxxxxxxx@xxxxxxxxxx> Date: Sat, 25 May 2002 21:38:49 +0200 To: linuxtrent@freelists.org Subject: [Linuxtrent] Re: Lock di un file
Daniele Nicolodi writes:
> Quali sono le soluzioni su un sistema unix per fare il lock di un file ??
Fondamentalmente hai due sistemi:
-
Advisory lock tramite link (simbolici o non)
E` “advisory” nel senso che e` compito dei processi comportarsi “per bene” e controllare che il lock in questione non ce l’abbiano altri.
Se vuoi acquisire il lock, devi semplicemente tentare di creare un link (hard o simbolico) con un nome noto al file in questione.
La cosa interessante di link(2) e symlink(2) e` che entrambe sono atomiche (quindi o vanno e creano il link, oppure falliscono con errno == EEXIST, per cui vuol dire che un altro ha gia` acquisito il lock).
Quando vuoi rilasciare il lock, semplicemente elimini il link.
Lo svantaggio e` che se il processo che tiene il lock va in crash, il link simbolico, e bisogna cancellarlo a mano, e non so se la cosa funzioni bene via NFS.
I demoni che fanno uso di questo sistema per fare dei lock, tipicamente li creano in /var/lock.
-
Advisory lock tramite open() con O_CREAT + O_EXCL
Variante della 1, solo che qui si crea un file, sfruttando il fatto che open(2) e` atomica, e quando e` chiamata con O_CREAT + O_EXCL fallisce con errno == EEXIST. Stessi difetti.
Nella manpage di open(2) leggo che pero` non funziona con NFS
-
Advisory lock tramite fcntl(2), che pare funzioni anche via NFS
E` descritta molto bene nelle pagine info della libreria del C, nodo “File Locks”, e non dovrebbe lasciare in giro lock “spuri” anche se il processo crepa inaspettatamente.
Il mandatory locking (quello che ti fa fallire open() o read() o write()) non mi pare ci sia in Linux (e sotto questo aspetto e` un BSD), mentre c’e` nei vari System V. Pero`, perche` sia veramente mandatory, occorre anche che il file in questione da lockare sia SETGID senza permessi di esecuzione (che normalmente non ha molto senso, visto che il bit setgid ha senso solo per gli eseguibili).
> Quali di queste sono “portabili” su altre piattaforme ???
- e (2), forse anche (3), se per “altre piattaforme” intendi “altri *NIX”.
Per “altre piattaforme” che sono veramente “altre piattaforme”, probabilmente ti conviene crearti delle funzioni ad hoc da implementare caso per caso.
— Matteo Ianeselli
1 Addendum di Marco Cova
Anche Linux supporta mandatory locking. La cosa e’ un po’ (volutamente) involuta e i passi necessari per farlo sono:
1) rimontare il file system con l’opzione mand (nomand fa l’opposto): mount /dev/root / -o mand,remount L’opzione mand non e’ documentata in nessuna delle man page di mount che abbia visto e per trovarlo ho dovuto trafficare un po’ con la documentazione del kernel o direttamente con fs/locks.c 🙁
2) marcare un file come candidato al mandatory lock, esattamente come ha detto Matteo: SGUID bit settato e execution bit per il gruppo non settato.
3) usare lockf() o fcntl(), la prima e’ piu’ comoda e sostanzialmente non e’ altro che un wrapper attorno alla seconda.
Nota che e’ possibile anche lockare solo una regione del file, anziche’ l’intero file. Nota ancora che se locki il file con un write lock, open () fallisce (e a meno di non specificare che deve essere non bloccante, si blocca!); se invece acquisisci un read lock, l’accesso in sola lettura e’ permesso anche ad altri processi.
Reference varie: – man page di lockf, fcntl – linux/Documentation/{locks.txt,mandatory.txt} – linux/fs/locks.c – Stevens ne parla piuttosto diffusamente sia in Advanced Programming in Unix Environment che in Unix Networking
Addenda: cat /proc/locks mostra la locks table e un grosso MANDATORY ti dice che il lock in questione e’ del secondo tipo. Li’ trovi anche il pid del processo che detiene il lock, cosi’ che le cose vanno havoc sai chi uccidere. cat /proc/mount o mount senza parametri ti mostra i file system montati e le opzioni di mount (mount a dire il vero legge queste info da /etc/mtab che potrebbe non essere completo, vedi l’opzione -n di mount)
HTH, Marco Cova
PS: qualche giorno fa e’ uscito su bugtraq un’advisory su un possibile !DoS ai danni di sendmail utilizzando advisory locking. Come sempre, attenzione a quando e come si lockano i file 🙂
-