точность отметки времени прикосновения на EXT4 - PullRequest
4 голосов
/ 17 ноября 2010

Обновление : Оказывается, я был очень глупым. Я проверял время модификации, когда я должен был проверять время доступа. Причина, по которой это было невозможно воспроизвести, заключалась в том, что тестовые файлы были созданы с dd if=/dev/urandom of="$target" bs='1K' count=1 || exit 1, что большую часть времени было слишком быстрым, чтобы время модификации (конец dd) новых файлов отличалось от времени доступа (начало время dd). Еще одна вещь, которую нужно остерегаться.

Я работаю над сценарием, чтобы применить время доступа одного файла плюс два года к другому файлу. Это использует stat -c %x, date --rfc-3339=ns и touch -a --date="$result". stat и date обе выводят строки даты с наносекундами, например

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

и info coreutils 'touch invocation' говорят, что он поддерживает наносекунды. Но иногда при применении касания есть небольшая разница между примененной меткой времени и меткой, возвращенной впоследствии stat. Вот данные из фактического прогона:

$ 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,938 мс и медианой 4,001 мс. Есть идеи, что может вызвать это?

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

Ответы [ 2 ]

0 голосов
/ 09 мая 2012

Touch в Windows 7 64 бит приносит аналогичные проблемы. Это мой код эксплойта:

touch a && touch b && ls --full-time a b
touch -r a b && ls --full-time a 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.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

ls и touch происходят от gnuwin32. В первых двух выходных строках разница во времени составляет 20 мс. Хорошо. Но во втором прогоне они должны быть равны (b взял штамп от a). Неудачно. Разница в 0,7 с нами:).

svn status видит разницу и, следовательно, ее трудно обмануть с помощью touch.

0 голосов
/ 17 ноября 2010

Я использовал эту кучу (по общему мнению, быстрых и грязных) 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

Мне не удалось воспроизвести вашу проблему ни разу. Звучит так, будто прикосновение не получает ожидаемую метку времени в параметре -d, но что-то вычисляется иначе.

Конечно, проблема может быть связана с системой, и в этом случае нам потребуется дополнительная информация о вашей системе (процессор, 32-разрядная или 64-разрядная ОС, версии kernel / glibc / coreutils и т. Д.).

UPDATE:

Я попробовал то же самое с 32-битными версиями stat и touch. Никаких проблем не возникло. Ядро все еще было 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

Опять проблема не обнаружена. Я пробовал это с опциями монтирования relaytime и strictatime.

Update3:

Я только что выполнил вышеописанные тесты на своем ноутбуке Mandriva i686. Кажется, у меня тоже нет проблем с точностью до наносекунды. Я также проверил на другой 32-битной системе, что если точность наносекунды не поддерживается (например, на ext3), поле наносекунды в выходных данных статистики становится равным нулю.

...