Estou trabalhando com enormes quantidades de memória flash USB.
Eu gostaria de poder rastrear eventos relacionados às unidades USB.
Especificamente: eu executo f3
testes, formando as unidades e escrevo dados para elas.
Estou procurando uma maneira de marcar as unidades digitalmente (por exemplo, com um UUID) para que eu possa executar várias ações com a unidade, mantendo os números de série intactos. Espero que outras pessoas também usem e formatem as unidades, ainda permitindo que eu leia o número de série delas depois.
Eu tentei usar o número de série informado pelo dispositivo USB, mas logo descobri que a maioria das unidades não possui informações de identificação armazenadas nelas.
Por isso - cansei de gerar um UUID concatenado com sua própria soma de CRC para que eu possa escrever a string no drive e lê-la de volta, verificando se ela foi armazenada corretamente.
Gravar o número de série no sistema de arquivos, no entanto, significa que, uma vez que a unidade estiver preenchida, todas as cópias do número de série serão sobrescritas.
Minha ideia mais recente é particionar a unidade para deixar 1 MB de espaço vazio não particionado para que eu possa armazenar o número de série lá.
Isso terá um impacto marginal na utilidade de uma unidade, mas deve permitir que eu identifique unidades de forma confiável, contanto que a unidade não seja reparticionada.
Idealmente, cada unidade teria um UUID gravado no chip do driver Mass Storage e reportaria isso - mas eu não fabrico as unidades.
Pensei em gerar os números de série um pouco assim (Bash):
UUID=$(uuidgen)
CK=$(echo "$UUID" | cksum | cut -c -8)
SN="SN:$UUID:$CK;"
echo $SN
Isso gera um UUID, calcula uma soma de CRC desse UUID, deixa apenas 8 primeiros caracteres dessa soma (porque o comprimento pode variar e precisamos de um comprimento constante para pesquisar efetivamente o padrão posteriormente). Em seguida, ele concatena que com alguns marcadores que podem ser usados para extrair o número formam um fluxo de dados e verificar se ele não foi danificado.
Números de série de exemplo:
SN:7199e42e-465b-4baf-96b6-a109247d3f4b:39272476;
SN:aa795142-fa2e-4929-b93b-e991f95a74cd:40619286;
SN:43f93702-eda9-4089-9a81-d21172e051bf:37174302;
Eu posso verificar a integridade do número de série assim:
SN="SN:7199e42e-465b-4baf-96b6-a109247d3f4b:39272476;"
UUID=$(echo "$SN" | cut -d':' -f2)
CK=$(echo "$SN" | cut -d':' -f3 | cut -d';' -f1)
if [[ $(echo "$UUID" | cksum | cut -c -8) == $CK ]]; then
echo "SN is fine"
else echo "SN is corrupted"; fi
Eu também posso extrair um número de série de uma unidade com grep
:
cat /dev/sdX | grep -E "SN:.{8}-.{4}-.{4}-.{4}-.{12}:.{8};" -o
Depois, recebo uma lista de números de série e avalio-os até encontrar um que tenha uma soma de verificação correspondente.
Como trabalho com unidades potencialmente com falhas, preciso gravar o número de série em várias cópias para que pelo menos uma cópia sobreviva.
Eu me pergunto se há uma abordagem melhor para o que estou tentando fazer - sem, claro, recorrer à fabricação de minha própria memória flash,
EDIT: UDEVADM
Eu posso tentar obter um identificador único usando várias informações somente leitura da própria unidade:
$ udevadm info /dev/sdd | grep -e "ID_MODEL" -e "ID_SERIAL" -e "ID_VENDOR"
E: ID_MODEL=Flash_Disk
E: ID_MODEL_ENC=Flash\x20Disk\x20\x20\x20\x20\x20\x20
E: ID_MODEL_ID=6387
E: ID_SERIAL=Generic_Flash_Disk_97C06F44-0:0
E: ID_SERIAL_SHORT=97C06F44
E: ID_VENDOR=Generic
E: ID_VENDOR_ENC=Generic\x20
E: ID_VENDOR_ID=058f
$ udevadm info /dev/sdd | grep -e "ID_MODEL" -e "ID_SERIAL" -e "ID_VENDOR" | md5sum | cut -d' ' -f1
7b7f63b829b6301cdf35d71eed9bb707
Estou quase certo, no entanto, que encontrarei muitas unidades que retornam valores idênticos aqui - tornando essa abordagem inútil.
EDIT2:
Eu acumulei quase 1600 pontos de dados sobre isso, e a maioria das unidades parece produzir hashes exclusivos, mas eu ainda consegui cerca de 400 unidades que retornaram hashes idênticos, então esse método sozinho não é suficiente.