Esta rename()función es equivalente para archivos normales a la definida por el estándar ISO C. Su inclusión aquí amplía esa definición para incluir acciones en directorios y especifica el comportamiento cuando el nuevo parámetro nombra un archivo que ya existe. Esa especificación requiere que la acción de la función sea atómica.
#include <stdio.h>
int rename(const char *old, const char *new);
Descripción
La renamefunción hace que el archivo cuyo nombre es la cadena señalada por oldsea conocido en adelante por el nombre dado por la cadena señalada por new. El nombre del archivo oldya no es accesible con ese nombre. Si un archivo nombrado por la cadena a la que apunta newexiste antes de la llamada a la renamefunción, el comportamiento está definido por la implementación.
Devoluciones
La renamefunción devuelve cero si la operación tiene éxito, no cero si falla, en cuyo caso si el archivo existía anteriormente, todavía se conoce por su nombre original.
Sorprendentemente, tenga en cuenta que no hay un requisito explícito para la atomicidad. Es posible que se requiera en otro lugar en el último estándar C disponible públicamente, pero no he podido encontrarlo. Si alguien puede encontrar ese requisito, las ediciones y los comentarios son más que bienvenidos.
Si newpathya existe, será reemplazado atómicamente, de modo que no haya ningún punto en el que otro proceso que intente acceder
newpathlo encuentre perdido. Sin embargo, probablemente habrá una ventana en la que ambos oldpathy se newpathrefieren al archivo que se renombra.
La página de manual de Linux afirma que el reemplazo del archivo será atómico.
Sin embargo, probar y verificar que la atomicidad podría ser muy difícil, si es así de lejos debe llegar. No tiene claro qué quiere decir con su uso de "¿Cómo puedo verificar si mv es atómico"? ¿Desea requisitos / especificaciones / documentación que sea atómica, o necesita realmente probarlo ?
Tenga en cuenta también que lo anterior supone que los dos nombres de archivo de operando están en el mismo sistema de archivos. No puedo encontrar ninguna restricción estándar en la mvutilidad para hacer cumplir eso.
Tengo que asegurarme de que el movimiento sea atómico. ¿Está probando lo suficiente para aceptar esto? No puedo decirlo Sí, estoy trabajando en un mismo fs (ext4 a ext4).
Tizianoreica
1
POSIX tampoco garantiza la atomicidad, pero Linux, como la mayoría de las variantes de Unix, sí lo hace para sistemas de archivos "nativos" como ext4.
Gilles 'SO- deja de ser malvado'
1
Dado que ISO C solo define el comportamiento de un programa y no de un sistema completo, sería extraño que dijera algo sobre renameatomicidad.
Gilles 'SO- deja de ser malvado'
3
Leí "esa especificación" como una referencia a la oración anterior ("Su inclusión aquí ... especifica el comportamiento cuando el nuevo parámetro nombra un archivo que ya existe"), que hace referencia a partes anteriores del documento POSIX ("un enlace llamado nuevo debe permanecer visible para otros hilos a lo largo de ... y consultar el archivo al que hacen referencia nuevos o viejos ... "). En otras palabras, POSIX promete implementar el estándar ISO C y ofrece garantías adicionales más allá de lo que proporciona ISO C. ¿Ayuda esa interpretación?
SimonJ
1
@Tizianoreica Sé que esta es una publicación antigua, pero acabo de ver tu comentario y pensé que debería aclarar: El sistema de archivos real debe ser el mismo para que el cambio de nombre sea atómico. No solo el mismo tipo de sistema de archivos. por ejemplo, si tiene /un ext4 fs y /tmpun ext4 fs diferente, entonces no puede moverse atómicamente de uno a otro.
Wodin
0
mvse basa en la renamellamada al sistema y rename()es atómico. Podrías mirar la página del manual rename(2).
Además de verificar las llamadas al sistema y su atomicidad, quizás inotify-toolspueda servir como prueba, aunque no estoy seguro de si es una prueba garantizada de atomicidad.
Abrir 2 conchas. Mire el directorio de destino del movimiento en uno de ellos:
inotifywait -m target/
Mueva un archivo al directorio en el otro:
mv foobar target/
El inotifywaitdebería mostrar solo una línea:
target/ MOVED_TO foobar
Parece atómico en comparación con la respuesta a ls target/y touch target/a, que produce mensajes multilínea como:
# the response to ls target/
target/ OPEN,ISDIR
target/ ACCESS,ISDIR
target/ CLOSE_NOWRITE,CLOSE,ISDIR
PD
Creo que, al menos, muestra que la cooperación multiproceso asíncrona en archivos es segura con inotify(prácticamente atómica): en cualquier caso, respondería solo después de inotifydar la señal final después de la operación. Por ejemplo, una configuración de productor-consumidor se puede implementar de manera fácil y segura con inotify.
strace
?unlink
orename
atómicamentelink
?Respuestas:
Curiosamente, parece que la respuesta puede ser "depende".
Para que quede claro,
mv
se especifica aLa especificación de la función renombrar establece:
Pero la última especificación ISO C para
rename()
estados:Sorprendentemente, tenga en cuenta que no hay un requisito explícito para la atomicidad. Es posible que se requiera en otro lugar en el último estándar C disponible públicamente, pero no he podido encontrarlo. Si alguien puede encontrar ese requisito, las ediciones y los comentarios son más que bienvenidos.
Ver también ¿Es rename () atomic?
Según la página de manual de Linux :
La página de manual de Linux afirma que el reemplazo del archivo será atómico.
Sin embargo, probar y verificar que la atomicidad podría ser muy difícil, si es así de lejos debe llegar. No tiene claro qué quiere decir con su uso de "¿Cómo puedo verificar si mv es atómico"? ¿Desea requisitos / especificaciones / documentación que sea atómica, o necesita realmente probarlo ?
Tenga en cuenta también que lo anterior supone que los dos nombres de archivo de operando están en el mismo sistema de archivos. No puedo encontrar ninguna restricción estándar en la
mv
utilidad para hacer cumplir eso.fuente
rename
atomicidad./
un ext4 fs y/tmp
un ext4 fs diferente, entonces no puede moverse atómicamente de uno a otro.mv
se basa en larename
llamada al sistema yrename()
es atómico. Podrías mirar la página del manualrename(2)
.Podrías encontrar la respuesta en Is rename () atomic? en stackoverflow.
¿Qué tipo de fs usaste?
fuente
Además de verificar las llamadas al sistema y su atomicidad, quizás
inotify-tools
pueda servir como prueba, aunque no estoy seguro de si es una prueba garantizada de atomicidad.Abrir 2 conchas. Mire el directorio de destino del movimiento en uno de ellos:
Mueva un archivo al directorio en el otro:
El
inotifywait
debería mostrar solo una línea:Parece atómico en comparación con la respuesta a
ls target/
ytouch target/a
, que produce mensajes multilínea como:PD
Creo que, al menos, muestra que la cooperación multiproceso asíncrona en archivos es segura con
inotify
(prácticamente atómica): en cualquier caso, respondería solo después deinotify
dar la señal final después de la operación. Por ejemplo, una configuración de productor-consumidor se puede implementar de manera fácil y segura coninotify
.fuente