كيفية معرفة ما إذا كان جهاز SCSI (على سبيل المثال /etc/sda) عبارة عن قرص أم لا عبر مكالمات ioctl أو غيرها؟
سؤال
كيفية معرفة ما إذا كان جهاز SCSI (على سبيل المثال /dev/sda) عبارة عن قرص أم لا عبر مكالمات ioctl أو غيرها؟لقد حاولت ما يلي ولكن ioctl
فشل المكالمة.My /dev/sda هو قرص فلاش USB.
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <scsi/scsi.h>
#include <scsi/sg.h>
#include <sys/ioctl.h>
int main(int argc, char** argv) {
char *dev = "/dev/sda";
struct sg_scsi_id m_id;
int rc;
int fd;
fd = open(dev, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
perror(dev);
}
memset(&m_id, 0, sizeof (m_id));
rc = ioctl(fd, SG_GET_SCSI_ID, &m_id);
if (rc < 0) {
close(fd);
printf("FAIL: ioctl SG_GET_SCSI_ID, rc=%d, errno=%d\n", rc, errno);
} else {
if (m_id.scsi_type == TYPE_DISK || m_id.scsi_type == 14) {
printf("OK: is disk\n");
} else {
printf("OK: is NOT disk\n");
}
}
close(fd);
return (EXIT_SUCCESS);
}
// result is: FAIL: ioctl SG_GET_SCSI_ID, rc=-1, errno=22
المحلول
لقد قمت بحل هذا باستخدام SG_IO
وتفسير البيانات الثنائية مباشرة وفقًا لمواصفات أمر الاستفسار (مجال:نوع الجهاز الطرفي) وتفسيرها وفقًا لذلك أنواع الأجهزة الطرفية SCSI (هو القرص إذا كان لكل.ديف.النوع إما 00h أو 0Eh)
int is_disk_sd(char *dev) {
unsigned char sense[32];
struct sg_io_hdr io_hdr;
char scsi_data[SCSI_LEN];
struct hd_geometry geo;
// request for "standard inquiry data"
unsigned char inq_cmd[] = {INQUIRY, 0, 0, 0, SCSI_LEN, 0};
int fd;
fd = open(dev, O_RDONLY | O_NONBLOCK);
if (fd < 0) {
perror(dev);
}
memset(&io_hdr, 0, sizeof (io_hdr));
io_hdr.interface_id = 'S';
io_hdr.cmdp = inq_cmd;
io_hdr.cmd_len = sizeof (inq_cmd);
io_hdr.dxferp = scsi_data;
io_hdr.dxfer_len = sizeof (scsi_data);
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
io_hdr.sbp = sense;
io_hdr.mx_sb_len = sizeof (sense);
io_hdr.timeout = 5000;
if (ioctl(fd, SG_IO, &io_hdr) < 0) {
close(fd);
return 0;
} else {
close(fd);
if (scsi_data[1] & 0x80) {
return 0; // support is removable
}
if ((scsi_data[0] & 0x1f) || ((scsi_data[0] & 0x1f) != 0xe)) { // 0 or 14 (00h or 0Eh)
return 0; // not direct access neither simplified direct access device
}
return 1;
}
}
نصائح أخرى
ربما يمكنك الحصول على معلومات مفيدة من/sys/bus/scsi/devices/*/filesystem.
HDIO_GET_IDENTITY
يبدو أنه يعمل بالنسبة لي على الأقراص ولكن ليس على محركات الأقراص. أعتقد أن هذا هو ما hdparm -i
الاستخدامات.
لا تنتمي إلى StackOverflow