2010-11-17 44 views
4

更新:原來我很笨。我正在檢查修改時間,當我應該檢查訪問時間。不可重複的原因是測試文件是用dd if=/dev/urandom of="$target" bs='1K' count=1 || exit 1製作的,其大部分時間對於新文件的修改時間(dd的末尾)來說太快而不同於訪問時間(開始時間爲dd) 。另一件需要注意的事情。EXT4上的觸摸時間戳準確性

我正在處理一個腳本,將一個文件加兩年的訪問時間應用到另一個文件。這使用stat -c %x,date --rfc-3339=nstouch -a --date="$result"statdate兩個輸出日期字符串與納秒,像

2012-11-17 10:22:15.390351800+01:00 

,並info coreutils 'touch invocation'表示支持納秒。但是有時在應用觸摸時,應用的時間戳與統計之後返回的時間戳之間存在細微的差異。這裏的數據從實際運行:

$ for i in {1..100}; do ./t_timecopy.sh 2>/dev/null| grep ASSERT; done 
ASSERT:Expecting same access time expected:<2012-11-17 10:58:40.719320935+01:00> but was:<2012-11-17 10:58:40.723322203+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:00:04.342346275+01:00> but was:<2012-11-17 11:00:04.346358718+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:00:39.343348183+01:00> but was:<2012-11-17 11:00:39.347351686+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:01:08.655348312+01:00> but was:<2012-11-17 11:01:08.659347625+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:01:37.930346876+01:00> but was:<2012-11-17 11:01:37.934347311+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:02:16.939319832+01:00> but was:<2012-11-17 11:02:16.943323061+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:02:46.456443149+01:00> but was:<2012-11-17 11:02:46.458379114+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:03:15.487339595+01:00> but was:<2012-11-17 11:03:15.491341426+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:04:04.646335863+01:00> but was:<2012-11-17 11:04:04.650346634+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:04:14.410326608+01:00> but was:<2012-11-17 11:04:14.414331233+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:04:24.159367348+01:00> but was:<2012-11-17 11:04:24.163352418+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:04:33.931387953+01:00> but was:<2012-11-17 11:04:33.935350115+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:05:03.394361030+01:00> but was:<2012-11-17 11:05:03.398320957+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:05:42.054317430+01:00> but was:<2012-11-17 11:05:42.059106497+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:06:40.346320820+01:00> but was:<2012-11-17 11:06:40.350346956+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:08:17.194346778+01:00> but was:<2012-11-17 11:08:17.198338832+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:08:27.102347603+01:00> but was:<2012-11-17 11:08:27.106320380+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:09:16.247322948+01:00> but was:<2012-11-17 11:09:16.251347966+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:09:55.191325266+01:00> but was:<2012-11-17 11:09:55.195320672+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:12:09.915318301+01:00> but was:<2012-11-17 11:12:09.919334099+01:00> 
ASSERT:Expecting same access time expected:<2012-11-17 11:12:28.906346914+01:00> but was:<2012-11-17 11:12:28.910348186+01:00> 

所以21出的100次測試失敗,以3.938ms的平均值和4.001 ms的中位數。任何想法可能導致這種情況?

$ uname -a 
Linux user 2.6.32-22-generiC#33-Ubuntu SMP Wed Apr 28 13:27:30 UTC 2010 i686 GNU/Linux 
+0

如果您提供了您正在使用的測試腳本的代碼,它將對我們有所幫助。另外,你是否完全確定在你這樣做的時候什麼都沒有讀(注意:atime)這些文件? – thkala 2010-11-17 17:11:45

+0

這可以解釋它:-)。您還應該記住兩件事:1.僅僅因爲FS支持納秒級分辨率,並不意味着內核實際上使用這種分辨率來計算任何事情。 2.有時是敏感的事情。你需要用strictatime mount選項明確地打開它們,這會顯着降低FS(通常默認爲relatime)的性能。他們也容易受到任何隨機應用程序訪問您正在觀看的文件。 – thkala 2010-11-18 17:19:18

回答

0

我用這一堆(誠然快速&髒)oneliners來測試我的系統上您的問題 - 一個的Mandriva Linux 2010.1(X86-64):

seq 1 1000 | while read f; do sleep 0.01; touch test-$f-0; done 

seq 1 1000 | while read f; do touch -a -d "$(stat -c %x test-$f-0 | sed 's|^2010|2012|')" test-$f-1; done 

seq 1 1000 | while read f; do A="$(stat -c %x test-$f-0)"; B="$(stat -c %x test-$f-1)"; if [[ ! "${A#2010}" = "${B#2012}" ]]; then echo test-$f; fi; done 

我無法重現您問題甚至一次。這聽起來像touch不是在-d參數上輸入預期的時間戳,而是以其他方式計算的。

當然,這個問題可能是系統特定的,在這種情況下,我們需要有關係統的更多信息(CPU,OS 32或64位,kernel/glibc/coreutils版本等)。

UPDATE:

我試圖與統計和觸摸的32位版本的相同。沒有問題出現。內核仍然是一個64位的內核。

UPDATE2:

我也試過這一套oneliners,即更注重的atime:

$ seq 1 1000 | while read f; do sleep 0.01; touch test-$f-0; done 
$ seq 1 1000 | while read f; do sleep 0.01; touch test-$f-1; done 
$ seq 1 1000 | while read f; do sleep 0.01; cat test-$f-0; done 
$ seq 1 1000 | while read f; do touch -a -d "$(stat -c %x test-$f-0 | sed 's|^2010|2012|')" test-$f-1; done 
$ seq 1 1000 | while read f; do A="$(stat -c %x test-$f-0)"; B="$(stat -c %x test-$f-1)"; if [[ ! "${A#2010}" = "${B#2012}" ]]; then echo test-$f; fi; done 

同樣沒有檢測到的問題。我嘗試了relatime和strictatime掛載選項。

UPDATE3:

我剛剛執行上面我的Mandriva i686的筆記本電腦的測試。我似乎也沒有得到納秒級精度的問題。我還在另一個32位系統上驗證過,如果不支持納秒精度(例如,在ext3上),stat狀態輸出中的納秒字段將變爲零。

+0

即使文件系統輪換時間,您的測試也不會捕獲它,因爲測試中唯一的時間源是文件系統本身通過stat(1)。 – unbeli 2010-11-17 14:56:41

+0

根據問題,OP希望「將一個文件加上兩年的訪問時間應用於另一個文件」。他已經在使用FS作爲參考。 – thkala 2010-11-17 16:14:05

+0

@unbeli,OP似乎有的問題是,觸摸-a -d「每當」沒有正確設置「when when」作爲文件的atime。 「何時」來自哪裏實際上是無關緊要的。 – thkala 2010-11-17 16:29:30

0

在Windows 7 64位觸摸帶來類似的問題。這是我的攻擊代碼:

touch a && touch b && ls --full-time a b 
touch -r a b && ls --full-time a b 

和輸出:來自的GnuWin32

-rw-rw-rw- 1 Jarek 0 0 2012-05-09 12:05:27.851839700 +0200 a 
-rw-rw-rw- 1 Jarek 0 0 2012-05-09 12:05:27.874841000 +0200 b 

-rw-rw-rw- 1 Jarek 0 0 2012-05-09 12:05:27.851839700 +0200 a 
-rw-rw-rw- 1 Jarek 0 0 2012-05-09 12:05:27.851839000 +0200 b 

lstouch。在前2個輸出行中,時間戳差異爲20 ms。好。但在第二輪中他們應該是平等的(ba拿到了印章)。沒有運氣。有一個0.7 us的差異:)。

svn status看到了區別,因此很難用touch來欺騙它。