Pregunta

¿Cuál es la forma correcta de cambiar el nombre de un archivo de forma duradera en un sistema de archivos POSIX? En concreto se pregunta sobre fsyncs en el directorios . (Si esto depende del OS / FS, estoy preguntando por Linux y ext3 / ext4).

Nota: : hay otras preguntas sobre stackoverflow sobre cambios de nombre duraderos, pero no lo hacen AFAICT dirección de fsync-ción de los directorios (que es lo que me importa - Ni siquiera estoy modificando los datos del archivo ).

Actualmente tengo (en Python):

dstdirfd = open(dstdirpath, O_DIRECTORY|O_RDONLY)
rename(srcdirpath + '/' + filename, dstdirpath + '/' + filename)
fsync(dstdirfd)

Las preguntas específicas

  • ¿Esto también implícitamente fsync el directorio de origen? O puede ser que termino con el archivo aparecer en ambos directorios después de un ciclo de potencia (lo que significa que tendría que comprobar el número de enlaces dura y realizar manualmente la recuperación), es decir que es imposible garantizar una operación de movimiento de forma duradera atómica?
  • Si fsync el directorio de origen en lugar de el directorio de destino, hará que también implícitamente fsync la carpeta de destino?
  • ¿Hay alguna prueba relacionada útil / depuración / herramientas (inyectores de falla, herramientas de introspección, sistemas de archivos falsos, etc.) El aprendizaje?

Gracias de antemano.

¿Fue útil?

Solución

POSIX define que el href="http://pubs.opengroup.org/onlinepubs/009695399/functions/rename.html" rel="nofollow noreferrer"> función de cambio de nombre .

Así que si cambia el nombre (A, B), en ningún caso debería ver alguna vez un estado con el archivo en ambos directorios o ni directorio. Siempre habrá exactamente una, no importa lo que haces con fsync () o si el sistema se bloquea.

Pero eso no resuelve el problema de asegurarse de que la operación de cambio de nombre () es duradera. POSIX responde a esta pregunta :

Si se define _POSIX_SYNCHRONIZED_IO, la función fsync () será forzar todo actualmente en cola I / O operaciones asociadas con el archivo indicado por fildes de descriptor de archivo para el estado de finalización de E / S sincronizada. Todas las operaciones de E / S se completaron como se define para sincronizada I / O finalización integridad de los archivos.

Así que si fsync () un directorio, en espera de las operaciones de cambio de nombre se debe transferir al disco por el momento esto devuelve. fsync () de cualquiera de directorio debe ser suficiente, ya que la atomicidad de la operación de cambio de nombre () requeriría que los cambios ambos directorios pueden sincronizar de forma atómica.

Por último, en contraste con la reclamación en el blog mencionado en otra respuesta, la razón de esto explica lo siguiente:

La función fsync () tiene la intención de forzar una escritura física de los datos de la caché del búfer, y para asegurar que después de un fallo del sistema o de otra falla que todos los datos hasta el momento de la llamada fsync () se registra en el disco. Dado que los conceptos de "buffer cache", "caída del sistema", "escritura física", y "almacenamiento no volátil" no se definen aquí, la redacción ha de ser más abstracto.

Un sistema que pretendía ser compatible con POSIX y que considerado comportamiento correcto (es decir, no un error o fallo de hardware) para completar un fsync () y no persistir esos cambios a través de una caída del sistema tendría que ser deliberadamente tergiversar sí con respecto con la especificación.

(actualiza con información adicional re: específica de Linux vs comportamiento portátil)

Otros consejos

Lamentablemente la respuesta de Dave es incorrecta.

No todos los sistemas POSIX incluso podría tener un almacenamiento duradero. Y si lo hacen, todavía es “permitido” sea regado después de un fallo del sistema. Para aquellos sistemas un fsync no-op () tiene sentido, y tal fsync () se permite explícitamente en POSIX. También es válido para el archivo que sea recuperable en el directorio anterior, el nuevo directorio, ambos, o cualquier otro lugar. POSIX no ofrece ninguna garantía para el sistema se bloquea o recuperaciones del sistema de archivos.

La verdadera pregunta debería ser:

¿Cómo hacer un cambio de nombre duradera en los sistemas de los que el apoyo que a través de la API POSIX?

Es necesario hacer un fsync () en ambos, la fuente y se supone directorio de destino, debido a que el mínimo los fsync () s que hacer es persisten cómo directorio de origen o de destino debe ser similar.

¿Tiene un fsync (destdirfd) también implícitamente fsync el directorio de origen?

  • POSIX en general: no, nada implica que
  • ext3 / 4: No estoy seguro de si ambos cambios a la fuente y el destino DIR terminan en la misma transacción en la revista. Si lo hacen, reciben tanto comprometidos juntos.

O puede ser que termino con el archivo aparecer en ambos directorios después de un ciclo de potencia ( “crash”), es decir que es imposible garantizar una operación de movimiento de forma duradera atómica?

  • POSIX en general: no hay garantías, pero se supone que fsync () ambos directorios, que podría no ser atómica duradera
  • ext3 / 4: la cantidad de fsync () que mínimamente necesita depende de las opciones de montaje. P.ej. si se monta con “sincronización de directorios” no necesita cualquiera de los dos fsync () s. A lo sumo se necesita tanto fsync () s, pero estoy casi seguro de uno es suficiente (atómica duradera a continuación).

Si fsync el directorio de origen en lugar del directorio de destino, hará que también implícitamente fsync la carpeta de destino?

  • POSIX: sin
  • ext3 / 4: Realmente creo que ambos terminan en la misma transacción, por lo que no importa cuál de ellos fsync ()
  • kernels antiguos de ext3: (si no están en la misma transacción) alguna aplicación no tan óptima hizo demasiado sincronización de fsync (), apuesto a que cometió cada transacción que vino antes. Y sí, una aplicación normal de primera vincularía al destino y luego eliminarlo de la fuente. Por lo que el fsync (srcdirfd) desencadenaría la fsync () del destino también.
  • ext4 / ext3 última: si no están en la misma transacción, que podría ser capaz de sincronización por completo de forma independiente (por lo tanto hacen)

¿Hay alguna utilidad relacionada prueba / depuración / aprendizaje de herramientas (inyectores de falla, herramientas de introspección, sistemas de archivos falsos, etc.)?

Para un desplome de las propiedades, no. Por cierto, un accidente real, va más allá del punto de vista del núcleo. El hardware podría cambiar el orden de las escrituras (y dejar de escribir todo), corrompiendo el sistema de archivos. Ext4 está mejor preparado contra esto, porque permite barries escritura (opciones de montaje) de forma predeterminada (ext3 no lo hace) y puede detectar la corrupción con sumas de comprobación de revistas (también una opción de montaje).

Y para el aprendizaje: averiguar si los cambios tanto de alguna manera están vinculados en la revista! :-P

La respuesta a su pregunta va a depender mucho en el sistema operativo concreto que se utilice, el tipo de sistema de archivos que se utiliza y si la fuente y dest son en el mismo dispositivo o no.

me gustaría empezar leyendo la (2) página de manual de cambio de nombre de la plataforma que está utilizando.

Me suena como que está tratando de hacer el trabajo del sistema de archivos. Si mueve un archivo del núcleo y sistema de archivos son responsables de la operación atómica y de fallo de recuperación, no su código.

En cualquier caso, este artículo parece responder a sus preguntas con respecto a fsync: http://blogs.gnome.org/ AlexL / 2009/03/16 / ext4-vs-fsync-mi-take /

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top