|
|
|
@ -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. |
|
|
|
* 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; |
|
|
|
union ccb *ccb = 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; |
|
|
|
*pt_failed = 0; |
|
|
|
*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 */ |
|
|
|
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(product, sizeof(product), "%.16s", inq_data->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 */ |
|
|
|
@ -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; |
|
|
|
|
|
|
|
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)); |
|
|
|
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, buf_len); |
|
|
|
// Извлекаем модель
|
|
|
|
if (model_buf && model_len > 0) { |
|
|
|
char real_model[41]; |
|
|
|
memcpy(real_model, ident_buf->model, sizeof(ident_buf->model)); |
|
|
|
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; |
|
|
|
} else { |
|
|
|
*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; |
|
|
|
|
|
|
|
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)); |
|
|
|
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, buf_len); |
|
|
|
// Извлекаем модель
|
|
|
|
if (model_buf && model_len > 0) { |
|
|
|
char real_model[41]; |
|
|
|
memcpy(real_model, ident_buf->model, sizeof(ident_buf->model)); |
|
|
|
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; |
|
|
|
} |
|
|
|
|
|
|
|
@ -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) { |
|
|
|
char path[MAXPATHLEN]; |
|
|
|
char model_buf[256]; |
|
|
|
char serial_buf[64]; /* <-- Новый буфер для серийника */ |
|
|
|
char type_buf[16]; |
|
|
|
off_t mediasize = 0; |
|
|
|
|
|
|
|
snprintf(path, sizeof(path), "/dev/%s", base_disk); |
|
|
|
strlcpy(model_buf, "Generic Drive", sizeof(model_buf)); |
|
|
|
serial_buf[0] = '\0'; /* <-- Инициализируем пустым значением */ |
|
|
|
strlcpy(type_buf, "unknown", sizeof(type_buf)); |
|
|
|
|
|
|
|
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; |
|
|
|
|
|
|
|
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) { |
|
|
|
@ -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 */ |
|
|
|
lua_pushstring(L, model_buf); lua_setfield(L, -2, "model"); |
|
|
|
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 */ |
|
|
|
char size_buf[32]; |
|
|
|
|