Browse Source

Add reading serial number from disk

master
Sergey Kiselev 3 months ago
parent
commit
febb8aaf5a
  1. 1
      examples/test.lua
  2. 67
      src/diskinfo.c

1
examples/test.lua

@ -22,6 +22,7 @@ for _, disk_name in ipairs(disks._order) do
print(string.format("Drive: %s [%s] | Type: %s%s", disk_name, disk.size, disk.type, smart_str)) print(string.format("Drive: %s [%s] | Type: %s%s", disk_name, disk.size, disk.type, smart_str))
print(string.format(" |- Hardware Model : %s", disk.model)) print(string.format(" |- Hardware Model : %s", disk.model))
print(string.format(" |- Serial Number : %s", disk.serial))
print(" |- Partition Tree :") print(" |- Partition Tree :")
if #disk.mounts._order == 0 then if #disk.mounts._order == 0 then

67
src/diskinfo.c

@ -95,7 +95,12 @@ static void get_base_disk(const char *dev_name, char *base_buf, size_t buf_len)
* For 'ada' (SATA) devices: Sends native ATA IDENTIFY command. * For 'ada' (SATA) devices: Sends native ATA IDENTIFY command.
* Successfully bypasses all controller bugs to read real struct ata_params. * Successfully bypasses all controller bugs to read real struct ata_params.
*/ */
static void query_cam_properties(const char *base_disk, char *model_buf, size_t buf_len, int *is_removable, int *is_ssd, int *pt_failed, int *temp) { static void query_cam_properties(
const char *base_disk,
char *model_buf, size_t model_len,
char *serial_buf, size_t serial_len, /* <-- Добавили аргумент */
int *is_removable, int *is_ssd, int *pt_failed, int *temp
) {
struct cam_device *cam_dev = NULL; struct cam_device *cam_dev = NULL;
union ccb *ccb = NULL; union ccb *ccb = NULL;
struct ata_params *ident_buf = NULL; struct ata_params *ident_buf = NULL;
@ -106,6 +111,7 @@ static void get_base_disk(const char *dev_name, char *base_buf, size_t buf_len)
*is_ssd = 0; *is_ssd = 0;
*pt_failed = 0; *pt_failed = 0;
*temp = -1; *temp = -1;
if (serial_buf && serial_len > 0) serial_buf[0] = '\0'; /* Инициализируем */
/* CRITICAL: Must use O_RDWR for transport-layer commands execution path to unlock */ /* CRITICAL: Must use O_RDWR for transport-layer commands execution path to unlock */
cam_dev = cam_open_device(base_disk, O_RDWR); cam_dev = cam_open_device(base_disk, O_RDWR);
@ -147,7 +153,7 @@ static void get_base_disk(const char *dev_name, char *base_buf, size_t buf_len)
snprintf(vendor, sizeof(vendor), "%.8s", inq_data->vendor); snprintf(vendor, sizeof(vendor), "%.8s", inq_data->vendor);
snprintf(product, sizeof(product), "%.16s", inq_data->product); snprintf(product, sizeof(product), "%.16s", inq_data->product);
clean_scsi_str(vendor); clean_scsi_str(product); clean_scsi_str(vendor); clean_scsi_str(product);
snprintf(model_buf, buf_len, "%s %s", vendor, product); snprintf(model_buf, model_len, "%s %s", vendor, product);
} }
/* 1b: SCSI SAT ATA PASS-THROUGH (16) -> IDENTIFY */ /* 1b: SCSI SAT ATA PASS-THROUGH (16) -> IDENTIFY */
@ -161,11 +167,24 @@ static void get_base_disk(const char *dev_name, char *base_buf, size_t buf_len)
cdb[0] = 0x85; cdb[1] = 4 << 1; cdb[2] = 0x08 | 0x02; cdb[4] = 1; cdb[14] = 0xEC; cdb[0] = 0x85; cdb[1] = 4 << 1; cdb[2] = 0x08 | 0x02; cdb[4] = 1; cdb[14] = 0xEC;
if (cam_send_ccb(cam_dev, ccb) == 0 && (ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { if (cam_send_ccb(cam_dev, ccb) == 0 && (ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
char real_model[41]; // Извлекаем модель
memcpy(real_model, ident_buf->model, sizeof(ident_buf->model)); if (model_buf && model_len > 0) {
real_model[sizeof(ident_buf->model)] = '\0'; char real_model[41];
ata_str_fix(real_model, sizeof(real_model)); memcpy(real_model, ident_buf->model, sizeof(ident_buf->model));
if (strlen(real_model) > 0) strlcpy(model_buf, real_model, buf_len); real_model[sizeof(ident_buf->model)] = '\0';
ata_str_fix(real_model, sizeof(real_model));
if (strlen(real_model) > 0) strlcpy(model_buf, real_model, model_len);
}
// Читаем серийник (размер serial в ata_params равен 20 байтам)
if (serial_buf && serial_len > 0) {
char real_serial[21];
memcpy(real_serial, ident_buf->serial, sizeof(ident_buf->serial));
real_serial[sizeof(ident_buf->serial)] = '\0';
ata_str_fix(real_serial, sizeof(real_serial));
if (strlen(real_serial) > 0) strlcpy(serial_buf, real_serial, serial_len);
}
if (ident_buf->media_rotation_rate == 1) *is_ssd = 1; if (ident_buf->media_rotation_rate == 1) *is_ssd = 1;
} else { } else {
*pt_failed = 1; *pt_failed = 1;
@ -206,11 +225,24 @@ static void get_base_disk(const char *dev_name, char *base_buf, size_t buf_len)
ccb->ataio.cmd.command = 0xEC; ccb->ataio.cmd.command = 0xEC;
if (cam_send_ccb(cam_dev, ccb) == 0 && (ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { if (cam_send_ccb(cam_dev, ccb) == 0 && (ccb->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) {
char real_model[41]; // Извлекаем модель
memcpy(real_model, ident_buf->model, sizeof(ident_buf->model)); if (model_buf && model_len > 0) {
real_model[sizeof(ident_buf->model)] = '\0'; char real_model[41];
ata_str_fix(real_model, sizeof(real_model)); memcpy(real_model, ident_buf->model, sizeof(ident_buf->model));
if (strlen(real_model) > 0) strlcpy(model_buf, real_model, buf_len); real_model[sizeof(ident_buf->model)] = '\0';
ata_str_fix(real_model, sizeof(real_model));
if (strlen(real_model) > 0) strlcpy(model_buf, real_model, model_len);
}
// Читаем серийник
if (serial_buf && serial_len > 0) {
char real_serial[21];
memcpy(real_serial, ident_buf->serial, sizeof(ident_buf->serial));
real_serial[sizeof(ident_buf->serial)] = '\0';
ata_str_fix(real_serial, sizeof(real_serial));
if (strlen(real_serial) > 0) strlcpy(serial_buf, real_serial, serial_len);
}
if (ident_buf->media_rotation_rate == 1) *is_ssd = 1; if (ident_buf->media_rotation_rate == 1) *is_ssd = 1;
} }
@ -245,11 +277,13 @@ static void get_base_disk(const char *dev_name, char *base_buf, size_t buf_len)
static void get_disk_properties(lua_State *L, const char *base_disk) { static void get_disk_properties(lua_State *L, const char *base_disk) {
char path[MAXPATHLEN]; char path[MAXPATHLEN];
char model_buf[256]; char model_buf[256];
char serial_buf[64]; /* <-- Новый буфер для серийника */
char type_buf[16]; char type_buf[16];
off_t mediasize = 0; off_t mediasize = 0;
snprintf(path, sizeof(path), "/dev/%s", base_disk); snprintf(path, sizeof(path), "/dev/%s", base_disk);
strlcpy(model_buf, "Generic Drive", sizeof(model_buf)); strlcpy(model_buf, "Generic Drive", sizeof(model_buf));
serial_buf[0] = '\0'; /* <-- Инициализируем пустым значением */
strlcpy(type_buf, "unknown", sizeof(type_buf)); strlcpy(type_buf, "unknown", sizeof(type_buf));
if (strncmp(base_disk, "nvme", 4) == 0 || strncmp(base_disk, "nvd", 3) == 0) { if (strncmp(base_disk, "nvme", 4) == 0 || strncmp(base_disk, "nvd", 3) == 0) {
@ -275,7 +309,8 @@ static void get_disk_properties(lua_State *L, const char *base_disk) {
int smart_temp = -1; int smart_temp = -1;
if (strncmp(base_disk, "ada", 3) == 0 || strncmp(base_disk, "da", 2) == 0) { if (strncmp(base_disk, "ada", 3) == 0 || strncmp(base_disk, "da", 2) == 0) {
query_cam_properties(base_disk, model_buf, sizeof(model_buf), &is_removable, &is_ssd, &pt_failed, &smart_temp); /* Передаем новый буфер в CAM функцию */
query_cam_properties(base_disk, model_buf, sizeof(model_buf), serial_buf, sizeof(serial_buf), &is_removable, &is_ssd, &pt_failed, &smart_temp);
} }
if (strcmp(type_buf, "unknown") == 0) { if (strcmp(type_buf, "unknown") == 0) {
@ -292,6 +327,12 @@ static void get_disk_properties(lua_State *L, const char *base_disk) {
/* Push properties into the Lua table current on top of stack */ /* Push properties into the Lua table current on top of stack */
lua_pushstring(L, model_buf); lua_setfield(L, -2, "model"); lua_pushstring(L, model_buf); lua_setfield(L, -2, "model");
lua_pushstring(L, type_buf); lua_setfield(L, -2, "type"); lua_pushstring(L, type_buf); lua_setfield(L, -2, "type");
/* !!! NEW !!! Отдаем серийный номер в Lua, если он определился */
if (strlen(serial_buf) > 0) {
lua_pushstring(L, serial_buf);
lua_setfield(L, -2, "serial");
}
/* Format storage size with binary standards */ /* Format storage size with binary standards */
char size_buf[32]; char size_buf[32];

Loading…
Cancel
Save