Почему `- modify-window = 1` при использовании команды rsync?

Вы также можете ознакомиться с этим фантастическим ответом о надежном определении имени (и версии) вашей ОС. На основе на этот ответ вы можете сделать что-то вроде:

RHEL_VERSION="$(lsb_release -r | awk '{print $NF}')"

, а затем использовать любой из других ответов, предоставленных для извлечения основного номера версии. Преимущество в том, что этот подход работает для большего количества дистрибутивов, чем RHEL.

Если вы уверены, что номер версии будет чисто числовым (с десятичной точкой, разделяющей старшие и второстепенные числа, вы можете сделать все это одним махом:

RHEL_MAJOR_VERSION="$(lsb_release -r|awk '{printf "%d\n",$N}')"

2
08.08.2018, 16:53
2 ответа

Во избежание путаницы в отношении того, как работает окно модификации _, оно проверяется в любом направлении. (Если вы хотите прочитать это в исходном коде, отметьте util.c ::cmp _time ().)

Это значит,

  • если A новее, чем B, он проверяет, является ли A новее, чем B + модифицирует окно _.
  • если B новее, чем A, он проверяет, является ли B новее, чем A + модифицирует окно _.

Итак, предположим, что исходный A имеет время 123, но ваша резервная файловая система паршивая, поэтому копия B заканчивается либо временем 122 (, что делает A новее, чем B ), либо временем 124 (, делая B новее чем A ).

Что произойдет, если изменить _окно = 1?

  • Если A (123 )новее, чем B (122 ), он проверяет, является ли A (123 )более новым, чем B (122+1 = 123 ). ].
  • Если B (124 )новее, чем A (123 ), он проверяет, является ли B (124 )более новым, чем A (123+1 = 124 ).

В обоих случаях она оказывается одинаковой,поэтому изменить _window = 1 достаточно, чтобы время отклонялось на одну секунду в любом направлении.

Согласно справочной странице rsync, этого должно быть достаточно (tm )для FAT32.

Согласно приведенной вами документации (превращение 122 в 124, какого черта ), этого недостаточно.

Так что это неубедительно.


Экспериментально, используя NTFS (-3g )и FAT32 в Linux, изменение _window = 1 работает нормально.

Таким образом, моя тестовая установка была:

truncate -s 100M ntfs.img fat32.img
mkfs.ntfs -F ntfs.img
mkfs.vfat -F 32 fat32.img
mount -o loop ntfs.img /tmp/ntfs/
mount -o loop fat32.img /tmp/fat32/

Итак, файловая система NTFS/FAT32 объемом 100 МБ.

Создайте тысячу файлов с различными временными метками:

cd /tmp/ntfs

for f in {000..999}
do
    sleep 0.0$RANDOM # widens the timestamp range
    touch "$f"
done

Например:

# stat --format=%n:%y 111 222 333
111:2018-08-10 20:19:10.011984300 +0200
222:2018-08-10 20:19:13.553878700 +0200
333:2018-08-10 20:19:17.765753000 +0200

По вашему мнению, 20:19:10.011должно получиться как 2018-08-10 20:19:12.000.

Посмотрим, что получится. Сначала скопируйте все эти файлы в FAT32.

# rsync -a /tmp/ntfs/ /tmp/fat32/

Затем я заметил, что временные метки на самом деле точны, пока вы не размонтируете и не -смонтируете:

# umount /tmp/fat32
# mount -o loop fat32.img /tmp/fat32

Сравните:

# stat --format=%n:%y /tmp/{ntfs,fat32}/{111,222,333}
/tmp/ntfs/  111:2018-08-10 20:19:10.011984300 +0200
/tmp/fat32/ 111:2018-08-10 20:19:10.000000000 +0200
/tmp/ntfs/  222:2018-08-10 20:19:13.553878700 +0200
/tmp/fat32/ 222:2018-08-10 20:19:12.000000000 +0200
/tmp/ntfs/  333:2018-08-10 20:19:17.765753000 +0200
/tmp/fat32/ 333:2018-08-10 20:19:16.000000000 +0200

Так что это выглядит так, как будто меня это сбило с толку. Я не знаю, поступила бы так же Windows, но именно это происходит с Linux и rsync.

Что сделает rsync при повторном копировании:

# rsync -av --dry-run /tmp/ntfs/ /tmp/fat32
sending incremental file list
./
000
001
002
035
036
...
963
964
997
998
999

Таким образом, в списке есть пробелы, но в целом он -скопирует довольно много файлов.

При --modify-window=1список пуст:

# rsync -av --dry-run --modify-window=1 /tmp/ntfs/ /tmp/fat32/
sending incremental file list
./

Итак, по крайней мере, для Linux справочная страница точна. Кажется, что смещение никогда не превышает 1. (Ну, одна плюс дробь, но это тоже игнорируется.)


Итак, следует ли в любом случае использовать --modify-time=2? Нет, пока вы не сможете экспериментально показать, что это на самом деле возможное условие. Даже тогда трудно сказать. Во-первых, это ужасный взлом, и чем больше временное окно, тем больше вероятность того, что подлинные модификации будут упущены.

Даже --modify-time=1уже игнорирует изменения, которые не могут быть связаны со способом округления временных меток FAT32 -, так как он работает в обоих направлениях, но FAT32 всегда ограничивается только полами, и rsync игнорирует это при копировании в FAT32 (целевые файлы могут быть только старше ), и наоборот при копировании из FAT32 (целевые файлы могут быть только новее ).

Кажется, не существует варианта, чтобы справиться с этим лучше.


Я также пытался отследить это поведение в исходниках ядра, но, к сожалению, комментарии (в linux/fs/fat/misc.c )мало что дают для продолжения.

/*
 * The epoch of FAT timestamp is 1980.
 *     :  bits :     value
 * date:  0 -  4: day   (1 -  31)
 * date:  5 -  8: month (1 -  12)
 * date:  9 - 15: year  (0 - 127) from 1980
 * time:  0 -  4: sec   (0 -  29) 2sec counts
 * time:  5 - 10: min   (0 -  59)
 * time: 11 - 15: hour  (0 -  23)
 */

Таким образом, в соответствии с этим временная метка FAT использует 5 бит для секунд, поэтому вы получаете только 32 возможных состояния, из которых 30 используются. Преобразование выполняется простым битовым сдвигом.

в fs/fat/misc.c ::жир _время _unix2fat()

    /* 0~59 -> 0~29(2sec counts) */
    tm.tm_sec >>= 1;

Итак, 0 равно 0, 1 равно 0, 2 равно 1, 3 равно 1, 4 равно 2 и так далее...

в fs/fat/misc.c ::жир _время _fat2unix()

    second =  (time & 0x1f) << 1;

Противоположное приведенному выше, и 0x1f— это битовая маска для захвата только битов 0 -4 времени FAT, что представляет 0 -29 секунд.

Если это отличается от того, что должно быть, то в комментариях я ничего об этом не вижу.


Интересный пост Рэймонда Чена о том, почему Windows округляет время в большую сторону:https://blogs.msdn.microsoft.com/oldnewthing/20140903-00/?p=83

Okay, but why does the timestamp always increase to the nearest two-second interval? Why not round to the nearest two-second interval? That way, the timestamp change is at most one second.

Because rounding to the nearest interval means that the file might go backward in time, and that creates its own problems. (Causality can be such a drag.)

В соответствии с этим инструмент Windows xcopyимеет флаг /D, который говорит «копировать исходные файлы только в том случае, если они новее целевого файла». В основном то, что rsync --updateили cp --updateбудут делать.

Если округлить время в меньшую сторону, создав впечатление, что файлы были созданы на 1 секунду раньше, как это происходит в Linux, это приведет к тому, что файлы будут копироваться снова и снова каждый раз, когда вы запускаете команду. Округление времени в большую сторону исправляет это.

OTOH, решение для Windows вызывает ту же головную боль при обратном копировании этих файлов. Он будет копировать файлы, которые выглядят новее, чем они есть на самом деле, и тогда вы должны быть осторожны, чтобы сводка не повторилась дважды.

Независимо от того, что вы делаете, это всегда неправильно, файловая система, которая не может правильно хранить временные метки, просто мешает.

7
27.01.2020, 22:08

Вся приведенная выше математика доказывает, что если ваш раздел FAT32 округляется/усекается/увеличивается до 1 секунды, --modify-window=1является правильным ответом. Тем не менее :на моем разделе FAT32 я не могу найти файлы с нечетными секундами...:

ls -Rla --time-style=full-iso | grep '[13579]\.000000000 ' | wc -l

, а:

ls -Rla --time-style=full-iso | grep '[02468]\.000000000 ' | wc -l

показывает, что там много файлов.

Я придерживаюсь:--modify-window=2

1
27.01.2020, 22:08

Теги

Похожие вопросы