存储设备的设备唯一标识符 (DUID)

随着文件系统体系结构变得越来越复杂,操作系统组件的数量成倍增加,以及发起程序通过日益多样化的硬件和软件路径访问存储目标,识别存储设备的技术变得不足。

例如,即插即用 (PnP) 管理器为计算机中的每个设备生成实例标识符 (ID) 。 每个实例 ID 对应于设备树中的单个 设备 节点,如果设备仍位于同一位置,则唯一标识设备。 重启计算机时,实例 ID 会保留,但如果将设备移动到其他总线或另一台计算机,则实例 ID 不会保持不变。 因此,实例 ID 对于存储区域网络 (SAN) 的应用程序,以及某些较新的系统组件(如 Windows Vista 诊断服务)来说,这些组件在具有分布式存储的环境中运行,则实例 ID 不足。 当硬盘驱动器预测 SMART 故障时,它会为诊断服务生成事件。 此事件必须包含一个标识符,该标识符唯一标识磁盘可能位于的所有计算机上以及磁盘可能附加到的所有总线上的故障硬盘。 实例 ID 和任何其他 设备标识字符串 都不足以达到此目的。

某些应用程序和系统服务(如 Microsoft 群集服务 (MSCS) 和分区管理器)使用设备布局签名 (STORAGE_DEVICE_LAYOUT_SIGNATURE) 来唯一标识群集中的存储设备。 但在某些情况下,设备布局签名不足以达到此目的,并包含以下限制:

  • 签名可能会更改或被清除。

  • 如果设备未旋转或访问签名所在的扇区时遇到问题,则签名可能不可用。

  • 如果磁盘由另一个群集节点保留,则签名不可用。 MSCS 只能读取与运行 MSCS 的节点关联的磁盘的驱动器布局。 必须访问不同群集节点中的磁盘的软件必须使用磁盘布局签名的替代方法。

  • 驱动器布局签名无法帮助区分逻辑单元号 (LUN) 及其快照。 由于 LUN 及其快照具有相同的内容,因此其驱动器布局签名将相同。

序列号有时是唯一标识不依赖于设备位置的存储设备的可靠技术。 序列号通常作为设备查询数据的一部分提供。 发起方可以使用 IOCTL_STORAGE_QUERY_PROPERTY 请求查询查询数据,端口驱动程序在 STORAGE_DEVICE_DESCRIPTOR 结构中报告查询结果。 但是,此方法无助于识别不报告查询数据的设备,如磁带驱动器。

设备唯一标识符 (DUID)

由于唯一标识设备的技术通常会随着技术的发展而过时,Microsoft 开发了一种称为设备唯一 ID (DUID) 的设备 ID 格式,该格式是可扩展的,并且可以结合新技术在设备可用时识别设备。

DUID 由 STORAGE_DEVICE_UNIQUE_IDENTIFIER 结构定义,此结构的第一个版本 (DUID_VERSION_1) 包含以下标识符的组合:

STORAGE_DEVICE_ID_DESCRIPTOR
STORAGE_DEVICE_ID_DESCRIPTOR 结构包含从设备重要产品数据的页面0x83提取 (VPD) 的标识符。 通常,只有 SCSI 和光纤通道设备支持此页面。 集成驱动器电子 (IDE) 和通用串行总线 (USB) 设备、IEEE 1394 驱动器和 RAID 控制器不提供页面0x83。

STORAGE_DEVICE_DESCRIPTOR
STORAGE_DEVICE_DESCRIPTOR 结构包含其他查询数据,包括 SerialNumberOffset 成员中单位序列号的偏移量。 序列号的格式设置为长度可变、 以 NULL 结尾的字符串。 如果存储设备符合 SCSI,则端口驱动程序会尝试从 VPD 的可选“单位序列号”页 (页0x80) 提取序列号。 如果存储设备是 IDE 设备,则端口驱动程序会根据设备的标识数据生成序列号。

STORAGE_DEVICE_LAYOUT_SIGNATURE
STORAGE_DEVICE_LAYOUT_SIGNATURE包含设备布局签名。

未来版本中会向 DUID 添加更多数据。

DUID 没有固定大小,因此使用 DUID 的软件 (称为 DUID 使用者) 必须从 STORAGE_DEVICE_UNIQUE_IDENTIFIER 结构的 Size 成员获取 DUID 的大小。 此相同结构的 Vers****ion 成员中提供了 DUID 的版本。

某些设备没有为系统提供足够的信息,无法保证设备的 DUID 对于所有用途和所有 DUID 使用者而言都足够唯一。 如果操作系统可以从设备的 VPD 中检索唯一 ID,则可以创建对所有 DUID 使用者来说都足够唯一的 DUID。 但是,如果系统必须仅从设备布局签名创建 DUID,则 DUID 对于某些 DUID 使用者而言将足够唯一,但对于其他使用者则不是唯一的。

系统尝试创建具有以下特征的 DUID:

  • 操作系统重启时,DUID 保持不变。

  • 即使设备从一台计算机移动到另一台计算机、将适配器移动到另一台计算机或将一个通道移到另一台计算机,DUID 也保持不变。

  • DUID 标识设备,而不是媒体。 这种区别对于具有可移动媒体的驱动器非常重要。

  • 在多路径系统上,所有 I/O 路径的 DUID 都是相同的。

DUID 具有以下限制:

  • DUID 通常包含无法显示的二进制内容。

  • DUID 并不总是以 null 结尾。 DUID 使用者必须检查 STORAGE_DEVICE_LAYOUT_SIGNATURE 结构的 Size 成员来确定 DUID 的长度。

  • DUID 使用者必须使用 CompareStorageDuids 来比较 DUID,而不是按字节比较它们。

  • 枚举器不得出于即插即用 (PnP) 目的尝试使用 DUID 来标识设备对象。 多路径系统可以有多个共享同一 DUID 的设备。 但对于 PnP,设备 ID 必须是唯一的。

发起方可以使用属性 ID 为 StorageDeviceUniqueIdProperty的IOCTL_STORAGE_QUERY_PROPERTY请求来查询 DUID 信息数据。

如何比较 DUID

DUID 使用者必须使用 Storduids.h 中定义的 CompareStorageDuids 例程来比较两个 DUID。 CompareStorageDuids 返回一个 DUID_MATCH_STATUS 值,该值指示两个 DUID 是否匹配。 如果操作成功, CompareStorageDuids 将返回以下值之一:

DuidExactMatch
两个 DUID 中的所有字段完全匹配。

DuidSubIdMatch
DUID 由多个子 ID 组成。 至少有一个子 ID 匹配,两个 DUID 可能表示同一设备。 更新设备固件时,它可能会获取新的标识符,这将更改设备的 DUID 的构成。 如果 DUID 使用者将设备的旧 DUID 与新的 DUID 进行比较, CompareStorageDuids 可能会返回 DuidSubIdMatch 而不是 DuidExactMatch。 这是基于子 ID 的有效匹配的示例。 DUID 使用者必须根据 DUID 使用者的要求,选择是接受 DuidSubIdMatch 返回值作为匹配还是不匹配。

DuidNoMatch
序列号不匹配,并且重要产品数据第 83 小时页中的唯一子 ID (VPD) 不匹配。

除了上述值之外, CompareStorageDuids 可能返回各种错误代码。

CompareStorageDuids 例程使用以下算法来比较两个 DUID:

  1. 检查是否完全匹配。 如果 DUID 中的所有数据都匹配,则 DUID 完全匹配, CompareStorageDuids 返回 DuidExactMatch。 如果没有,请继续下一个检查。

  2. 检查 VPD 标识符。 如果任何唯一的子 ID 匹配,则 DUID 匹配, CompareStorageDuids 返回 DuidSubIdMatch。 如果没有子 ID 匹配,或者设备不提供唯一的 VPD 标识符,请继续下一个检查。

  3. 检查单位序列号。 如果供应商 ID、产品 ID 和序列号相同,则 DUID 匹配, CompareStorageDuids 返回 DuidSubIdMatch。 如果这些值都不匹配,或者设备未提供这些值,请继续下一个检查。

  4. 检查驱动器布局签名。 如果两个 DUID 的驱动器布局签名匹配,则 DUID 匹配,CompareStorageDuids 返回 DuidSubIdMatch。 如果驱动器签名不匹配或系统无法读取设备的驱动器布局签名,则 DUID 不匹配, CompareStorageDuids 返回 DuidNoMatch