file --preserve-date aendert die ctime und verstuemmelt die atime

Autor: Raphael Eiselstein <rabe_at_uugrn.org>
Datum: Tue, 12 Nov 2013 23:23:33 +0100
Hallo zusammen,

in einem script, mit dem ich Dateien in einem Verzeichnis scanne
(erfasse, inventarisiere), habe ich u.a. so ein Konstrukt verwendet:

file --mime-type --separator '|' --no-pad --raw --dereference \
        --preserve-date --files-from "${ALL_FILES_MIMETYPE_IN}"

Dieser Aufruf sorgt im Wesentlichen dafür, dass für alle Dateien, die 
in ${ALL_FILES_MIMETYPE_IN} enthalten sind geprüft werden und anhand von
charakteristischen Signaturen oder Mustern am Dateianfang ein Dateityp,
hier in der Form eines mime-types (zB text/plain) ausgegeben werden. 

Der Parameter --preserve-date soll dabei vermeiden, dass die sogenannte
atime (Access-Time) im Dateisystem verändert wird:

     -p, --preserve-date On systems that support utime(3) or utimes(2), 
        attempt to preserve the access time of files analyzed, to pretend
        that file never read them.

Effektiv passiert *scheinbar* folgendes: Der aktuelle Wert von atime
wird ermittelt (stat(2) ?), dann wird die Datei lesend geöffnet, um den
Dateianfang einzulesen, anschließend wird der vorige Wert von atime
*zurückgeschrieben*.

Davon abgesehen, dass dabei der Anteil der Nano-Sekunden abhanden kommt:
dabei wird offensichtlich die ctime verändert!!

Kurz gefasst: 
        --preserve-date soll *eigentlich* die atime erhalten, effektiv 
        wird die atime ganzzahlig abgerundet *und* die ctime wird auf
        das aktuelle Datum verändert. 

Man mag nun der Meinung sein, dass dieses Verhalten kontraintuitiv ist!

Mit http://sigsys.de/files/test_filetimes.sh kann man sich die Änderung
der verschiedenen Timestamps in Bezug auf verschiedene Zugriffe/Tools
ausgeben lassen. Dabei wird man das Problem mit --preserve-date
erkennen.






In meinem *speziellen* Anwendungsfall hat die unerwünschte Änderung der
ctime dazu geführt, dass der folgende Schritt im Script Dateien für eine 
Überprüfung der Chcksummen vorselektiert hat. Da zuvor *alle* Dateien
mittels "file --preserve-date" gelesen wurden, war bei allen Files die
ctime verändert worden. Das Ganze wird in sqlite ausgewertet:

-----------------------------------
...
insert into checksums_tmp (file_path,hashtype,hash_hex,x_before,x_current) 
 select f.file_path, b.hashtype, b.hash_hex,f.inode||f.size||f.mtime||f.ctime,b.inode||b.size||b.mtime||b.ctime 
   from files as f 
     left join index_before as b on f.file_path=b.file_path;
...
-----------------------------------

Weiter unten wird dann aufgrund von 

   ... where ... and  x_before <> x_current

ermittelt, dass die entsprechende Datei vermutlich modifiziert wurde und
daher die Checksumme neu erfasst werden muss.

Logisch falsch hierbei ist: für die Erkennung/Vermutung einer
Checksummen-relevanten Änderung einer Datei ist der Vergleich über 
(inode-size-mtime) ausreichend, da die ctime nur für den jeweiligen inode 
selbst (permissions, times, ...) verändert wird, zB durch obiges 
"file --preserve-date".
   
Korrekter ist hier der Stringvergleich von 
        f.inode||f.size||f.mtime (aktuell)
und     
        b.inode||b.size||b.mtime (vorher)


("||" concateniert strings)

Fazit:

* atimes sind für die Betrachtung von Dateiänderungen nahezu irrelevant
* mithin kann man also auf --preserve-date bei file(1) verzichten 
* und somit auch auf dessen Bug, dass dabei die ctime verändert wird

* außerdem spielt die ctime keine Rolle bei einer Vorauswahl, ob sich
  Checksummen (zB sha256) verändert haben könnten. 

  Checksummen ermitteln ist teuer, da dabei die jeweiligen Dateien 
  komplett gelesen werden müssen. Die Vorauswahl basierend auf 
  Metainformationen kann man schnell und effizient tabellarisch ermitteln: 

        find ${DESTDIR} -type f -printf '%p|%h|%f|%i|%n|%s|%U|%G|%TY-%Tm-%Td %TX|%CY-%Cm-%Cd %CX\n'

* Will man dennoch vermeiden, dass die Access time bei Lesezugriff auf
  Dateien verändert wird, muss man das jeweilige FS mit der Option
  "noatime" mounten:

mount(8): FILESYSTEM INDEPENDENT MOUNT OPTIONS
[...]
        noatime
                Do not update inode access times on this filesystem (e.g.,
                 for faster access on the news spool to speed up news servers).
[...]


Ich hoffe ich verbreite hier keine Falschinformation, vielleicht hilft
es irgendwann irgendwem und bei Fragen einfach fragen.

MfG
Raphael


-- 
Raphael Eiselstein <rabe@uugrn.org>               http://rabe.uugrn.org/
xmpp:freibyter@gmx.de  | https://www.xing.com/profile/Raphael_Eiselstein   
PGP (alt):            E7B2 1D66 3AF2 EDC7 9828  6D7A 9CDA 3E7B 10CA 9F2D
PGP (neu):            4E63 5307 6F6A 036D 518D  3C4F 75EE EA14 F625 DB4E
.........|.........|.........|.........|.........|.........|.........|..



-- 
UUGRN e.V. http://www.uugrn.org/
http://mailman.uugrn.org/mailman/listinfo/uugrn
Wiki: https://wiki.uugrn.org/UUGRN:Mailingliste
Archiv: http://lists.uugrn.org/

Empfangen am 12.11.2013

Dieses Archiv wurde generiert von hypermail 2.2.0 : 12.11.2013 CET