[megoldva - rtm] "Időutazás" fájl módosítási idő állításakor

Fórumok

Üdv,

A következő érdekességre bukkantam, egy Ubuntu 12.04.3 LTS rendszeren:

a fájl módosítási dátumok nem feltétlenül tükrözik az időbeli sorrendiséget.

Nézzünk egy példát:


date +%H:%M:%S.%N; touch x.x; ls -l --time-style=full-iso x.x | cut -f 7 -d " "

Tehát előbb kiiratom az aktuális időpontot, majd touch-csal beállítom a fájl módosítási idejét is. Ezt aztán szintén kiírom. Azt gondoltam, hogy az utóbbi időpontnak későbbinek kellene lennie.
Nos, ez nem feltétlenül igaz, mert ilyen értékek is kijöttek egymás után:

09:26:30.905796008 --> aktuális időpont
09:26:30.904820913 --> utána történt módosítás ideje

Oké, másodperc alatti eltérés van, annyira nem gond (ezer és egy dologból lehet, nyilván nem is biztos, hogy releváns az adat). Viszont van egy hálózati fájlrendszerem (most éppen GlusterFS), ott ez nagyobb is lehet:

09:28:00.787605257 --> aktuális
09:27:58.000000000 --> utána történt módosítás ideje

Ez viszont már problémás, például a make ilyenektől már el tud hasalni.

Valószínűleg látszik, hogy nem néztem meg túlzottan a belső működését a dolgoknak. De szerintem ez nem stimmel így. Mitől lehet? (Esetleg ha valakinél van kéznél FreeBSD, meg tudná nézni, hogy ott is ez van-e?)

Szerk: a gépek órái szinkronizálva vannak.

Hozzászólások

Ez egy shell optimalizacio, /bin/touch-csal mar jo lesz.

(sima touch-ot a shell a parse-olaskor vegrehajtja, gyak. touch x.x == >x.x)

Az a baj, hogy ha strace-szel követem a leírt sort végrehajtó shellt, akkor nem tudom reprodukálni a hibát.
Ha nincs raja strace és nem a /tmp-ben van az x.x, akkor elég gyakran ismétlődik a hiba(?).
Valamiért a /tmp alatt lenullázza a másodperc törtrészét.

GlusterFS-nél amúgy az van, hogy a másodpercnél "pontosabb" részt nullázza.

Szerk: Illetve ha a szerver és a kliens órája másképp jár pár másodperccel, akkor vannak nagyobb eltérések. Ami szerintem gáz, miért nem az író kliens ideje lesz a módosítás ideje?

Részemről feladva.
Nem ismerem eléggé a különböző rendszerhívásokat, hogy kiigazodjak rajtuk. Nem találom, honnan veszi a touch az időt.
Mivel nem lebegőpontos formában ábrázolják ezeket az értékeket, nincs sok ötletem...
Ha beraksz a touch elé egy sleep 1s parancsot, máris minden OK, de ez csak workaround, nem magyarázat. :)

Helyi idős problémára: a Linuxban több óra van, és szerintem az Ext4fs nem ugyanazt használja, mint a date. Lásd még http://stackoverflow.com/questions/6532088/diff-between-times-in-kernel…

A távoli fájlrendszernél hálózati átvitel ideje, kerekítés, plusz a fenti jelenség.

A jól beállított ntpd elvileg nem ugráltatja visszafelé az időt, viszont szerintem pont ez okozhat eltéréseket kernel és user space között. Túl mélyen nem ismerem ezeket, de szerintem nem lehet más magyarázat. De akár az is lehet, hogy totális hülyeséget beszélek.

--

The current time within the Linux kernel is cached, and generally only updated on a timer interrupt. So if your timer interrupt is running at 10 milliseconds, the cached time will only be updated once every 10 milliseconds.

date will call the gettimeofday system call which will always return the most accurate time available based on the cached kernel time, adjusted by the CPU cycle time if available to give nanosecond resolution. The timestamps stored in the file system however, are only based on the cached kernel time. ie The time calculated at the last timer interrupt.

Forrás:
http://stackoverflow.com/questions/14392975/timestamp-accuracy-on-ext4-…

Asszem, kitehetjük a MEGOLDVA előtagot, és levonhatjuk azt a következtetést, hogy itt még a legegyszerűbbnek tűnő júzerpúl tájékán is képes meglepetést okozni az alapokkal kapcsolatos apróbetűs részek nem ismerete.

Mellesleg köszönet a tanulságos problémáért és megoldásáért!

Sajnos FreeBSD-n nem tudom reprodukalni. A egfelelo ls opciot meg csak-csak tudom (-T), de az strftime nem mutat masodpercnel kisebb egyseg lekerdezesere alkalmas formatumot, igy a date-et nem tudom kelloen reszetes listazasra rabeszelni.