web-dev-qa-db-fra.com

Rename () est-il atomique?

Je ne suis pas en mesure de vérifier cela via des expériences et je n'ai pas pu le collecter à partir des pages de manuel également.

Supposons que j'ai deux processus, l'un déplaçant (renommant) le fichier1 du répertoire1 vers le répertoire2. Supposons que l'autre processus en cours d'exécution copie simultanément le contenu du répertoire1 et du répertoire2 vers un autre emplacement. Est-il possible que la copie se déroule de telle manière que le répertoire1 et le répertoire2 afficheront le fichier1 - c'est-à-dire que le répertoire1 est copié avant le déplacement et le répertoire2 après le déplacement par le premier processus.

Fondamentalement, est renommer () est un appel système atomique?

Merci

41
Lipika Deka

Oui et non.

rename () est atomique en supposant que le système d'exploitation ne plante pas. Il ne peut être divisé par aucun autre système de fichiers op.

Si le système plante, vous pourriez voir une opération ln () à la place.

Notez également que lorsque vous travaillez sur un système de fichiers réseau, vous pouvez obtenir ENOENT lorsque l'opération a réussi. Le système de fichiers local ne peut pas vous faire ça.

23
Joshua

C'est une réponse très tardive, mais ... oui rename() est atomique mais pas dans le sens de votre question. Sous Linux, rename(2) dit:

Cependant, lors du remplacement, il y aura probablement une fenêtre dans laquelle oldpath et newpath font référence au fichier à renommer.

Mais rename() est toujours atomique dans un sens très important: si vous l'utilisez pour écraser un fichier, vous vous retrouverez avec l'ancienne ou la nouvelle version et rien d'autre.

[pdate: mais comme le souligne @ jonas-wielicki dans les commentaires, vous devez vous assurer que le fichier que vous renommez a bien un contenu à jour, en utilisant fsync() et copains.]

Si newpath existe déjà, il sera atomiquement remplacé (sous réserve de quelques conditions; voir ERREURS ci-dessous), de sorte qu'il n'y ait aucun point auquel un autre processus tentant d'accéder à newpath le trouvera manquant.

Si vous voyez ERREURS, vous constaterez que le renommage peut échouer, mais il ne cassera jamais l'atomicité.

Tout cela provient de la page de manuel Linux. Ce que je ne sais pas, c'est si vous faites une rename() sur un système de fichiers réseau où le serveur exécute un système d'exploitation différent. Le client a-t-il alors un espoir d'en garantir l'atomicité? J'en doute.

24
Adrian Ratnapala

Je ne suis pas sûr que la partie "fondamentalement" de votre question soit valide. À moins que vous ayez une sorte de synchronisation entre les deux, peu importe le renommage atomique. Si la copie du répertoire arrive avant le changement de nom, vous allez avoir file1 aux deux endroits.

Je ne sais pas si vous vouliez parler de thread ou de processus, mais s'il existe des mécanismes de verrouillage pour les deux, les verrous de thread sont de loin les plus simples car ils n'ont pas à franchir les limites du processus.

6
boatcoder

le gnu libc manuel dit

Une caractéristique utile du changement de nom est que la signification de newname change "atomiquement" de tout fichier existant précédemment par ce nom à sa nouvelle signification (c'est-à-dire le fichier qui était appelé oldname). Il n'y a aucun instant où le nouveau nom est inexistant "entre" l'ancien sens et le nouveau sens. S'il y a un crash système pendant l'opération, il est possible que les deux noms existent toujours; mais le nouveau nom sera toujours intact s'il existe.

0
shaftdiesel