返回

使用 sg_ll_inquiry() 函数对 Linux 中的 scsi 设备进行查询操作

Linux

使用 sg_ll_inquiry() 对 Linux 中的 scsi 设备进行查询调用

问题:深入了解 scsi 设备

如果你想要深入了解 Linux 系统中的 scsi 设备,你需要一种方法来检索有关其功能的信息。这包括了解设备支持的页面代码,这些代码提供了特定数据和功能的详细信息。

解决方案:sg_ll_inquiry() 函数

要查询 scsi 设备并检索其支持的页面代码,你可以使用 sg_ll_inquiry() 函数。此函数是 scsi 工具包 (sg3_utils) 的一部分,可让你直接与 scsi 设备交互。

步骤:解析 SVPDL

sg_ll_inquiry() 函数返回一个缓冲区,其中包含来自设备的响应。要获取受支持的页面代码,你需要解析称为支持的 VPD 页列表 (SVPDL) 的数据结构。SVPDL 是一个字节数组,包含一个字节的长度字段,后面跟着一组字节,表示支持的页面代码。

深入探讨:获取更多信息

一旦你有了受支持的页面代码列表,你就可以针对这些页面代码执行其他查询调用。这使你能够检索更具体的信息,例如设备的序列号、固件版本和配置参数。

代码示例:C 语言

以下代码示例展示了如何在 C 中使用 sg_ll_inquiry() 函数:

#include <scsi/sg.h>
#include <stdio.h>
#include <stdlib.h>

int main() {
  int fd = open("/dev/sdc", O_RDONLY);
  if (fd < 0) {
    perror("open");
    return EXIT_FAILURE;
  }

  unsigned char buf[512];
  memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
  io_hdr.interface_id = 'S';
  io_hdr.cmd_len = 6;
  unsigned char cmd[6] = {0x12, 0, 0, 0, 0, 0};
  io_hdr.cmdp = cmd;
  io_hdr.dxfer_len = sizeof(buf);
  io_hdr.dxferp = buf;

  if (ioctl(fd, SG_IO, &io_hdr) < 0) {
    perror("ioctl");
    close(fd);
    return EXIT_FAILURE;
  }

  if (io_hdr.status != SG_STATUS_GOOD) {
    fprintf(stderr, "INQUIRY command failed: %s\n", sg_errstr(io_hdr.status));
    close(fd);
    return EXIT_FAILURE;
  }

  unsigned char *svpdl = buf + 4;
  int num_pages = svpdl[0];
  for (int i = 0; i < num_pages; i++) {
    printf("Supported page code: %02X\n", svpdl[i + 1]);
  }

  close(fd);
  return EXIT_SUCCESS;
}

结论:探索 scsi 设备的功能

通过使用 sg_ll_inquiry() 函数并解析 SVPDL,你可以揭开 Linux 中 scsi 设备的功能。此信息可用于优化性能、故障排除问题并充分利用这些重要存储设备。

常见问题解答

1. sg_ll_inquiry() 函数在哪里可用?

sg_ll_inquiry() 函数是 scsi 工具包 (sg3_utils) 的一部分,可以在大多数 Linux 发行版中找到。

2. 我需要特殊权限才能使用 sg_ll_inquiry() 吗?

是的,你需要具有 root 权限才能使用 sg_ll_inquiry() 函数。

3. 除了页面代码,我还可以使用 sg_ll_inquiry() 检索什么信息?

sg_ll_inquiry() 还可以用于检索设备类型、供应商和产品 ID 等基本信息。

4. 如何解析 SVPDL?

SVPDL 是一个字节数组,包含一个字节的长度字段,后面跟着一组字节,表示支持的页面代码。

5. 如何使用支持的页面代码执行其他查询调用?

可以使用 sg_ll_inquiry() 函数并指定要检索的特定页面代码来执行其他查询调用。