Dispositivo com porta USB para armazenamento do usuário - como detectar / como permitir desmontagens não seguras?

2

Estou tentando criar um dispositivo do tipo "appliance" simples executando um mínimo de Linux e algum código personalizado. Parte da funcionalidade que estou oferecendo é que o usuário pode conectar uma unidade flash USB ou disco rígido a uma porta USB específica e o dispositivo pode gravar dados em um sistema de arquivos no dispositivo.

Esta questão tem duas partes:

# 1: Como posso determinar o arquivo de dispositivo de bloqueio real para o dispositivo de armazenamento em massa USB que foi anexado a uma porta USB de hardware específica?

Simplesmente assumindo que o dispositivo de armazenamento USB sempre estará em /dev/sdb parece um pouco arriscado, porque suponha que um usuário conecte um hub à porta ou suponha que você obtenha um dispositivo com vários pontos de extremidade (por exemplo, um leitor de cartão). Além disso, suponha que o dispositivo seja reinicializado ou inicializado com um dispositivo USB na porta USB e, por qualquer motivo, o sistema decida tornar o dispositivo USB /dev/sda e o armazenamento interno /dev/sdb . (É concebível que o meio de inicialização para este dispositivo também seja USB, o que torna isso muito provável.)

Então o que eu basicamente quero ser capaz de fazer é dizer: "Dê-me o arquivo do dispositivo (como / dev / sdb) para o dispositivo USB de armazenamento em massa nesta específica porta USB." Se vários dispositivos de bloco forem encontrados em uma porta, eu gostaria de um "array" ou uma lista de todos os endpoints específicos para esse único dispositivo.

Para a instância em que alguém conecta um hub à porta e conecta vários flash drives a esse hub, eu ficaria bem com 1) nada aparecendo (e informando aos usuários que esses hubs não são permitidos e devem simplesmente conectar diretamente), ou 2) obter uma lista de todos os dispositivos de bloco conectados ao hub (semelhante a um dispositivo multi-endpoint).

Além disso, obviamente, se alguém anexar um dispositivo que não seja de armazenamento a essa porta, o método que eu usar não deve fornecer um nó de dispositivo de armazenamento.

# 2: Qual é a melhor prática para montar um sistema de arquivos para que ele possa ser removido com segurança sem primeiro desmontá-lo, desde que não ocorram gravações?

Obviamente, os usuários serão instruídos a nunca remover o dispositivo enquanto a luz estiver piscando, etc. No entanto, exigir que um usuário passe por um processo manual de desmontagem pode ser uma má experiência de uso para este dispositivo. (Ele terá uma UI muito mínima, portanto, implementar uma opção de remoção de hardware segura que seja fácil de acessar e usar seria um desafio.) Basicamente, o usuário deve ser capaz de puxar a unidade para fora assim que for visualmente óbvio que não há mais escrita está ocorrendo.

Obviamente, a maioria dos dispositivos conectados será vfat. Eu gostaria de também apoiar NTFS (via ntfs-3g) e exfat (via exfat-fusível).

Eu poderia simplesmente emitir sincronizações sempre que eu gravasse dados em meu próprio código, mas um caso de uso é um aplicativo externo que envia dados para o dispositivo USB em partes. Pense logger de dados. Um arquivo é criado e os dados são transmitidos para ele em partes, mas entre cada pedaço deve ser aceitável para o usuário puxar a unidade quando ela estiver entre gravações, fazer com que o sistema a detecte e interromper os dados logging, e ter a estrutura da unidade segura.

Além disso, assim que o dispositivo for puxado, preciso estar ciente disso rapidamente para que meu código possa remover a montagem e interromper as operações que possam estar esperando para ver a unidade.

Eu sei que estou pedindo muito para permitir aos usuários apenas puxar unidades à vontade, e, obviamente, se um usuário puxa uma unidade durante um escrever isso vai ser um problema, mas eu quero Permitir, no mínimo, o mais próximo deste Santo Graal que eu possa.

Idéias?

    
por fdmillion 31.12.2016 / 23:30

1 resposta

3

Para (1), eu sugeriria olhar para os udisks - eles já resolveram muito disso para você. Incluindo coisas como "o que acontece se o usuário conectar em dois dispositivos de armazenamento?" (lembre-se: hubs USB e, é claro, alguns dispositivos se apresentam como múltiplos). O udisks permite que você encontre facilmente os dispositivos disponíveis, seja notificado quando um deles estiver disponível (ou for removido), verifique vários atributos do dispositivo, etc. Ele também será compatível com a montagem - incluindo o suporte a uma ampla variedade de sistemas de arquivos.

Para (2), se possível, eu desmontaria o dispositivo entre as gravações. Caso contrário, você poderia montá-lo em sync e / ou dirsync mode, isso deve ajudar - isso deve manter o sistema de arquivos em um estado consistente entre as gravações. Além disso, se você gravar em um espaço pré-alocado, isso geralmente envolverá alterações de metadados do sistema de arquivos no mínimo (ou pelo menos no mínimo, apenas no mtime). (Quando você criar o log, escreva 10 MB de zero; em seguida, volte ao início e transmita seus dados para ele. Quando você atingir 10 MB, crie outro log. Apenas a operação de criação pouco frequente realmente arrisca a corrupção do sistema de arquivos.)

Como Julie Pelletier observou, no entanto, algum tipo de botão de ejeção seria preferível.

Além disso, como observação, se você pode fazer com que o aplicativo externo grave seus dados em um pipe (incluindo um nomeado criado com mkfifo ), seu código poderá ler o pipe e manipular a gravação real para USB. O mesmo se aplica se você tiver o aplicativo externo gravado em um arquivo temporário em um tmpfs.

    
por 01.01.2017 / 00:59