Package NFS

Fichiers du package

FichierDescription
nfslock.php

Gestion des verrous NFS

Proposer une amélioration

Liste des constantes

Valeur

  • 60

Package

Valeur

  • 'spip_nfs_lock'

Package

Liste des fonctions

(Excerpts from Chuck's notes: this becomes complex, due to our dear friend, the NFS mounted mail spool. the netbsd code didn't do this properly, as far as I could tell.

  • you can't trust exclusive creating opens over NFS, the protocol just doesn't support it. so to do a lock you have to create a tmp file and then try and hard link it to your lock file.

  • to detect a stale lock file you have to see how old it is, but you can't use time(0) because that is the time on the local system and the file gets the times of the NFS server. when is a lock file stale? people seem to like 120 or 300 seconds.)

NB: It is critical that nfslock()ed files be unlocked by nfsunlock(). Simply unlinking the lock file is a good way to trash someone else's lock file. All it takes is for the process doing the unlink to get hung for a few minutes when it doesn't expect it. Meanwhile, its lock expires and a second process forces the lock and creates its own. Then the first process comes along and kills the second process' lock while it's still valid.

Security considerations: If we're root, be very careful to see that the temp file we opened is what we think it is. The problem is that we could lose a race with someone who takes our tmp file and replaces it with, say, a hard link to /etc/passwd. Then, if the first lock attempt fails, we'll write a char to the file (see 4. below); this would truncate the passwd file. So we make sure that the link count is 1. We don't really care about any other screwing around since we don't write anything sensitive to the lock file, nor do we change its owner or mode. If someone beats us on a race and replaces our temp file with anything else, it's no big deal- the file may get truncated, but there's no possible security breach. ...Actually the possibility of the race ever happening, given the random name of the file, is virtually nil.

args: path = path to directory of lock file (/net/u/1/a/alexis/.mailspool) namelock = file name of lock file (alexis.lock) max_age = age of lockfile, in seconds, after which the lock is stale. stale locks are always broken. Defaults to DEFAULT_LOCKTIME if zero. Panix mail locks go stale at 300 seconds, the default. notify = 1 if we should tell stdout that we're sleeping on a lock

Returns the time that the lock was created on the other system. This is important for nfsunlock(). If the lock already exists, returns NFSL_LOCKED. If there is some other failure, return NFSL_SYSF. If NFSL_LOCKED is returned, errno is also set to EEXIST. If we're root and the link count on the tmp file is wrong, return NFSL_SECV.

Mods of 7/13/95: Change a bit of code to re-stat the lockfile after closing it. This is to work around a bug in SunOS that appears to to affect some SunOS 4.1.3 machines (but not all). The bug is that close() updates the stat st_ctime field for that file. So use lstat on fullpath instead of fstat on tmpfd. This alteration applies to both nfslock and nfslock1.

Mod of 5/4/95: Change printf's to fprintf(stderr... in nfslock and nfslock1.

Mods of 4/29/95: Fix freeing memory before use if a stat fails. Remove code that forbids running as root; instead, if root, check link count on tmp file after opening it.

Mods of 4/27/95: Return the create time instead of the lockfile's fd, which is useless. Added new routines nfsunlock(), nfslock_test(), nfslock_renew().

Mods of 1/8/95: Eliminate some security checks since this code never runs as root. In particular, we completely eliminate the safeopen routine. But add one check: if we are root, fail immediately.

Change arguments: take a path and a filename. Don't assume a global or macro pointing to a mailspool.

Add notify argument; if 1, tell user when we're waiting for a lock.

Add max_age argument and DEFAULT_LOCKTIME.

Change comments drastically.

integer | boolean spip_nfslock( string $fichier , integer $max_age )

Paramètres

  1. string $fichier

    Chemin du fichier

  2. integer $max_age

    Age maximum du verrou

Retour

  • integer | boolean

    Timestamp du verrou, false si erreur

Utilisé par

Package

Author

Proposer une amélioration

Args, return codes, and behavior are identical to nfsunlock except that nfslock_test doesn't remove the lock. NFSL_OK means the lock is good, NFLS_LOST and NFSL_STOLEN means it's bad, and NFSL_SYSF means we couldn't tell due to system failure.

The source for this routine is almost identical to nfsunlock(), but it's coded separately to make things as clear as possible.

void spip_nfslock_test( string $fichier , boolean $birth , integer $max_age )

Paramètres

  1. string $fichier

    Chemin du fichier

  2. boolean $birth

    Timestamp de l'heure de création du verrou

  3. integer $max_age

    Age maximum du verrou return bool true si déverrouillé, false sinon

Package

Author

Proposer une amélioration

This can get tricky because the lock may have expired (perhaps even during a process that should be "atomic"). We have to make sure we don't unlock some other process' lock, and return a panic code if we think our lock file has been broken illegally. What's done in reaction to that panic (of anything) is up to the caller. See the comments on nfslock()!

args: path = path to directory of lock file (/net/u/1/a/alexis/.mailspool) namelock = file name of lock file (alexis.lock) max_age = age of lockfile, in seconds, after which the lock is stale. stale locks are always broken. Defaults to DEFAULT_LOCKTIME if zero. Panix mail locks go stale at 300 seconds, the default. birth = time the lock was created (as returned by nfslock()).

Returns NFSL_OK if successful, NFSL_LOST if the lock has been lost legitimately (because more than max_age has passed since the lock was created), and NFSL_STOLEN if it's been tampered with illegally (i.e. while this program is within the expiry period). Returns NFSL_SYSF if another system failure prevents it from even trying to unlock the file.

Note that for many programs, a return code of NFSL_LOST or NFSL_STOLEN is equally disastrous; a NFSL_STOLEN means that some other program may have trashed your file, but a NFSL_LOST may mean that you have trashed someone else's file (if in fact you wrote the file that you locked after you lost the lock) or that you read inconsistent information.

In practice, a return code of NFSL_LOST or NFSL_STOLEN will virtually never happen unless someone is violating the locking protocol.

void spip_nfsunlock( string $fichier , boolean $birth , integer $max_age , boolean $test = false )

Paramètres

  1. string $fichier

    Chemin du fichier

  2. boolean $birth

    Timestamp de l'heure de création du verrou

  3. integer $max_age

    Age maximum du verrou

  4. boolean $test = false

    Mode de test return bool true si déverrouillé, false sinon

Voir également

Package

Author

Proposer une amélioration