Mac OS X - problema de tempo de modificação de arquivo exFAT

0

Eu encontrei um problema estranho com o rsync (sem -c, portanto, envolver o algoritmo de "verificação rápida" do rsync) ao copiar arquivos já sincronizados repetidamente para uma unidade formatada exFAT.

Os arquivos de origem envolvidos são armazenados em um volume HFS e foram criados por um processo automatizado de extração de imagens a partir de .docxdocumentos do Word e têm um tempo de modificação de 1 de janeiro de 1980 às 00:00:00, que também é o tempo mínimo suportado pelo carimbo de data / hora exFAT formato.

Após um rsync -adesses arquivos de destino no exFAT, o tempo de modificação é 1 de janeiro de 1980, 02:00:00.

Parece que o tempo mínimo suportado pelo meu driver OSF exFAT está desativado em duas horas.

E é por essa razão que o algoritmo de verificação rápida do rsync acredita que os arquivos são diferentes.

O teste a seguir parece confirmar isso:

# create a 10Mb exFAT disk image:
hdiutil create -size 10m -fs ExFAT -volname EXFATTEST exfattest.dmg

# attach the diskimage
hdiutil attach exfattest.dmg

# create a test file with a creation time of Jan 1, 1980 00:00:00
touch -t "198001010000.00" /Volumes/EXFATTEST/test1.txt
ls -lT /Volumes/EXFATTEST/test1.txt 
-rwxrwxrwx  1 user  staff  0 Jan  1 02:00:00 1980 /Volumes/EXFATTEST/test1.txt
#                                   ^^ off by two hours

# try a file with 3am
touch -t "198001010300.00" /Volumes/EXFATTEST/test2.txt
ls -lT /Volumes/EXFATTEST/test2.txt
-rwxrwxrwx  1 user  staff  0 Jan  1 03:00:00 1980 /Volumes/EXFATTEST/test2.txt
#                                   ^^ works as expected


# unmount the disk image
hdiutil detach /Volumes/EXFATTEST/

Um teste equivalente no Linux não mostra este erro:

truncate -s 10M exfattest.img
mkfs.exfat exfattest.img
mkdir /mnt/EXFATTEST/
mount -o loop exfattest.img /mnt/EXFATTEST/
touch -t "198001010000.00" /mnt/EXFATTEST/test.txt
ls --full-time /mnt/EXFATTEST/test.txt
rwxr-xr-x 1 root root 0 1980-01-01 00:00:00.000000000 +0100 /mnt/EXFATTEST/test.txt
#                                  ^^ correct modification time
umount /mnt/EXFATTEST/

Minha solução simples é atualizar o tempo de criação dos arquivos de origem usando touch.

No entanto, eu gostaria de saber se isso realmente é um bug e se alguém pode reproduzir esse erro em versões mais recentes do OS X, pois a Apple não permite que o meu iMac ainda perfeitamente funcionando no início de 2008 seja atualizado;)

Eu ainda estou no El Capitan:

sw_vers
ProductName:    Mac OS X
ProductVersion: 10.11.6
BuildVersion:   15G22010

Atualizar:

Depois de inspecionar a tabela exFAT, parece que meu driver El Capitan exFAT sempre usa 0xfcpara o LastModifiedTimezoneOffsetcampo de dados.

Esse valor de byte assinado especifica o deslocamento do UTC em incrementos de 15 minutos. 0xfcestá -4em decimal e seria interpretado como um deslocamento UTC negativo de uma hora.

Não sei por que o driver está fazendo isso, mas se ele usar um deslocamento estático de fuso horário de -1, também precisará sempre subtrair 1 hora do registro de data e hora UTC correspondente ao armazenar o carimbo de data e hora e adicionar 1 hora ao valor armazenado quando lendo o registro de data e hora do disco.

Isso basicamente funciona, a menos que o registro de data e hora UTC seja menor que 1º de janeiro de 1980 01:00, pois o registro de data e hora mínimo suportado de um arquivo no exFAT é 1º de janeiro de 1980 00:00.

Portanto, considero isso um bug, já que o driver exFAT do El Capitan não pode definir o carimbo de data e hora mínimo possível de modificação de arquivo suportado no exFAT.

O teste a seguir parece confirmar isso. Ele usa a TZvariável de ambiente para forçar o uso do fuso horário UTC, independentemente do fuso horário do sistema:

# set the minimum possible exFAT file modifification timestamp in UTC
TZ=UTC touch -t '198001010000.00' /Volumes/EXFATTEST/test.txt
# read back the stored timestamp in UTC
TZ=UTC ls -lT /Volumes/EXFATTEST/test.txt
-rwxrwxrwx  1 gollum  staff  0 Jan  1 01:00:00 1980 /Volumes/EXFATTEST/test.txt
#                                     ^^^^^^^^ ERROR: off by one hour

Mesmo erro ao criar um arquivo com esta data no HFS e copiá-lo para o volume exFAT:

# set Jan 1, 1980 00:00:00 on HFS (e.g. file in home directory)
TZ=UTC touch -t '198001010000.00' $HOME/test2.txt
TZ=UTC ls -lT $HOME/test2.txt
-rw-r--r--  1 gollum  staff  0 Jan  1 00:00:00 1980 /Users/gollum/test2.txt
#                                     ^^^^^^^^ CORRECT!

# copy the file to the exFAT volume and check the destination date
cp -a $HOME/test2.txt /Volumes/EXFATTEST/test2.txt
TZ=UTC ls -lT /Volumes/EXFATTEST/test2.txt
-rwxrwxrwx  1 gollum  staff  0 Jan  1 01:00:00 1980 /Volumes/EXFATTEST/test2.txt
#                                     ^^^^^^^^ ERROR: off by one hour

Outro teste interessante que fiz foi pegar a imagem de disco exFAT criada no linux (que contém o arquivo de teste com o registro de data e hora correto) e montá-la no OS X:

TZ=UTC ls -lT
total 0
-rwxrwxrwx  1 gollum  staff  0 Jan  1 00:00:00 1980 test.txt
#                                     ^^^^^^^^ correct!

No entanto, ao duplicar esse arquivo, a data é desativada por uma hora novamente. Portanto, pelo menos o driver OS X exFAT pode ler os carimbos de hora corretamente, mesmo que os arquivos sejam armazenados usando um 0xfcdeslocamento que não seja do fuso horário. Yay!

Agora, o contrário: montar o OS X dmg no Linux revela um segundo erro do driver exFAT do OS X:

mount -o loop exfattest.dmg /mnt/EXFATTEST/
FUSE exfat 1.0.1
ERROR: bad date 1980-01-00
#                       ^^^ OS X stored the DAY as zero ::facepalm::

Outro exemplo perfeito de falta de testes de esquina em desenvolvimento.

Esta é basicamente a resposta para minha pergunta. No entanto, aceitarei uma resposta que prove que minhas descobertas estão erradas ou as confirme e que também responda à minha pergunta se esse bug também ocorrer em versões mais recentes que as versões do El Capitan OS X.

Atualização 2:

Encontrei um post de Adam Harrison (um investigador forense digital do Reino Unido): Comportamento de carimbo de data / hora do exFAT associado a diferentes sistemas operacionais

Citação:

Ubuntu 16.04 e Ubuntu 18.04
Todos os fusos horários são registrados no UTC. Os campos de fuso horário são constantemente definidos como 00, indicando que não estão em uso.


Campos do fuso horário do OSX 10.13.3 - Definidamente definido como "FC", que é UTC-1 e não tenho idéia do porquê ...

Então, isso parece corresponder às minhas descobertas.

gollum
fonte

Respostas:

1

As implementações exFAT podem opcionalmente armazenar registros de data e hora UTC, em vez de registros de data e hora locais. (A maioria dos sistemas de arquivos modernos usa carimbos de data e hora UTC exclusivamente, mas o exFAT provavelmente desejou manter alguma compatibilidade com o FAT original.)

O driver macOS exFAT provavelmente foi gravado para usar o modo de carimbo de data / hora UTC - isso significa que, quando você especifica 1980-01-01 00: 00.00 (local) touch, está realmente pedindo ao driver que armazene 1979-12-31 23 : 00.00 (UTC) no disco.

Enquanto isso, o pacote exfat-utils do Linux usa a hora local e armazena os carimbos de data / hora com o deslocamento do fuso horário do sistema reaplicado; portanto, o 00:00 local também é armazenado como 00:00.

gravidade
fonte
não, veja o exemplo das 3h
gollum 03/01
O exemplo parece bom. Você deu touch03:00 hora local, foi traduzido para algo como 01:00 ou 02:00 UTC ao armazenar no disco. Em seguida, ele foi lida para trás de disco lse traduzido volta da UTC em 3:00 hora local antes de exibi-lo.
grawity
11
É realmente relacionado ao fuso horário, mas sua suposição está errada. Analisei a tabela FAT no meu editor hexadecimal e não importa qual fuso horário o sistema use, meu OSX sempre grava 0xFCpara todos os três (criar, modificar, acessar) TimezoneOffset. Esses valores são armazenados como bytes assinados ( 0xFCé -4 em decimal) e interpretados como deslocamento do UTC em incrementos de 15 min. Em outras palavras, o El Capitan sempre usa um deslocamento de fuso horário de UTC-01: 00 ao escrever carimbos de hora exFAT.
gollum 3/01
E também sobre a sua suposição sobre o linux exfat usando a hora local. Eu olhei para o despejo hexadecimal das imagens e ele usa 0x00para as compensações do fuso horário. Isso significa que o driver do fusível linux exfat armazena os registros de data e hora no UTC. No entanto, +1 por me fazer verificar se o bug está relacionado ao fuso horário, o que parece ser o caso.
gollum 04/01