Comment savoir si le périphérique SCSI (Say / dev / SDA) est un disque ou non via des appels IOCTL ou une autre? J'ai essayé ce qui suit mais l'appel code> ioctl code> échoue. Mon / dev / SDA est un disque flash 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
3 Réponses :
Peut-être que vous pouvez obtenir des informations utiles de / sys / bus / scsi / périphériques / * / duystème de fichiers. p>
Ty, cela aide, je vais creuser un peu plus pour le faire via IOCTL dur. [root @ localhost ~] # CAT / PROC / SCSI Dispositifs joints: hôte: SCSI1 CANAL: 00 ID: 00 LUN: 00 Vendeur: Sandisk Modèle: Cruzer Rev: 8.01 Type: Accès direct B> ANSI SCSI Révision: 02
hDIO_GET_Identity code> semble fonctionner pour moi sur des disques mais pas sur des lecteurs flash. Je pense que c'est ce que
HDPARM -I code> utilise. P>
Il fonctionne sur un disque SATA à l'aide de Libata pour apparaître sous la forme / Dev / SDA Code>. Je n'ai pas de disque SCSI à vérifier.
J'ai résolu ceci à l'aide de sg_io code> et interprétant les données binaires directement en fonction de la spécification du Commande de renseignements (champ: type de périphérique) et les interpréter selon Types de périphériques SCSI (est le disque si par. Dev. Type est soit 00h ou 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;
}
}