我正在使用大量 USB 闪存。我希望能够跟踪有关 USB 驱动器的事件。具体来说:我执行f3
测试、格式化驱动器并向其中写入数据。
我正在寻找一种以数字方式标记驱动器的方法(例如使用 UUID),以便我可以在保持序列号完好无损的情况下对驱动器执行各种操作。希望也有其他人使用和格式化驱动器,仍然允许我稍后读取它们的序列号。
我尝试过使用 USB 设备报告的序列号,但我很快发现大多数驱动器中都没有存储唯一的标识信息。
因此 - 我已经厌倦了生成与其自己的 CRC 和连接的 UUID,因此我可以将该字符串写入驱动器并将其读回,验证它是否正确存储。
然而,将序列号写入文件系统意味着一旦驱动器被填满,序列号的每个副本都将被覆盖。
我最新的想法是对驱动器进行分区,留下 1 MB 未分区的空白空间,这样我就可以在那里存储序列号。
这将对驱动器的实用性产生边际影响,但应该允许我在某种程度上可靠地识别驱动器,只要驱动器不会被重新分区。
理想情况下,每个驱动器都会将一个 UUID 写入大容量存储驱动器芯片并报告该情况 - 但我不制造驱动器。
我考虑过像这样生成序列号(Bash):
UUID=$(uuidgen)
CK=$(echo "$UUID" | cksum | cut -c -8)
SN="SN:$UUID:$CK;"
echo $SN
这会生成一个 UUID,计算该 UUID 的 CRC 和,只留下该和的前 8 个字符(因为长度可能会变化,并且我们需要一个恒定的长度来有效地搜索模式)。然后它将其与一些标记连接起来,这些标记可用于从数据流中提取数字并验证它是否未被损坏。
序列号示例:
SN:7199e42e-465b-4baf-96b6-a109247d3f4b:39272476;
SN:aa795142-fa2e-4929-b93b-e991f95a74cd:40619286;
SN:43f93702-eda9-4089-9a81-d21172e051bf:37174302;
然后我可以像这样验证序列号的完整性:
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
我还可以使用以下命令从驱动器中提取序列号grep
:
cat /dev/sdX | grep -E "SN:.{8}-.{4}-.{4}-.{4}-.{12}:.{8};" -o
然后我会得到一份序列号列表,并对它们进行评估,直到找到一个具有匹配校验和的序列号。
因为我使用可能有故障的驱动器,所以我需要将序列号写入多份副本,以便至少一份副本能够幸存。
我想知道是否有更好的方法来实现我正在尝试做的事情 - 当然无需诉诸于制造自己的闪存,
编辑:乌德瓦德
我可以尝试使用驱动器本身的各种只读信息来获取唯一标识符:
$ 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
然而,我几乎可以肯定,我会遇到很多在这里返回相同值的驱动器 - 使得这种方法毫无用处。
编辑2:
我已经积累了近 1600 个数据点,大多数驱动器似乎都会产生独特的哈希值,但我仍然有大约 400 个驱动器返回相同的哈希值,因此仅此方法是不够的。
答案1
设备的的ID_SERIAL
通常可以用来验证设备的身份。
它在各种格式中都是持久的,因为它是设备本身的属性;但是,据我所知,由于同样的原因,您无法更改它。
您可以通过运行来获取它:udevadm info /dev/sdX | grep ID_SERIAL=
答案2
持久设备命名(不同安装点上的名称相同)是一个难以实现的目标。在多个容器(文件系统、挂载点等)中创建了多个 UUID,如下所示详细描述在这里。
UUID(实际上是全球标识符 (WWID))由USB设备的硬件给出连接可以给出:
ls -l /dev/disk/by-id/
但请注意,并非所有设备都支持此类编号。
答案3
有些闪存在格式化后无法唯一识别,您最好的做法是设置自定义分区 UUID 或升级到更好的存储。
https://superuser.com/questions/1247972/change-uuid-of-vfat-partition