#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <scsi/scsi.h>
#include <scsi/sg.h>
#include <unistd.h>
#ifndef MAX_RAID_SERIAL_LEN
#define MAX_RAID_SERIAL_LEN 36
#endif
typedef unsigned char __u8;
int get_serial(int fd, void *buf, size_t buf_len)
{
unsigned char inq_cmd[] = {INQUIRY, 1, 0x80, 0, buf_len, 0};
unsigned char sense[32];
struct sg_io_hdr io_hdr;
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 = buf;
io_hdr.dxfer_len = buf_len;
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
io_hdr.sbp = sense;
io_hdr.mx_sb_len = sizeof(sense);
io_hdr.timeout = 5000;
return ioctl(fd, SG_IO, &io_hdr);
}
int read_serial(int fd, char *devname,
__u8 serial[MAX_RAID_SERIAL_LEN])
{
unsigned char scsi_serial[255];
int rv;
int rsp_len;
int len;
char *dest;
char *src;
char *rsp_buf;
int i;
memset(scsi_serial, 0, sizeof(scsi_serial));
rv = get_serial(fd, scsi_serial, sizeof(scsi_serial));
if (rv != 0) {
if (devname)
fprintf(stderr,
": Failed to retrieve serial for %s\n",
devname);
return rv;
}
rsp_len = scsi_serial[3];
if (!rsp_len) {
if (devname)
fprintf(stderr,
": Failed to retrieve serial for %s\n",
devname);
return 2;
}
rsp_buf = (char *) &scsi_serial[4];
/* trim all whitespace and non-printable characters and convert
* * ':' to ';'
* */
for (i = 0, dest = rsp_buf; i < rsp_len; i++) {
//printf("%c", *src);
src = &rsp_buf[i];
if (*src > 0x20) {
/* ':' is reserved for use in placeholder serial
* * numbers for missing disks
* */
if (*src == ':')
*dest++ = ';';
else
*dest++ = *src;
}
}
len = dest - rsp_buf;
dest = rsp_buf;
/* truncate leading characters */
if (len > MAX_RAID_SERIAL_LEN) {
dest += len - MAX_RAID_SERIAL_LEN;
len = MAX_RAID_SERIAL_LEN;
}
memset(serial, 0, MAX_RAID_SERIAL_LEN);
memcpy(serial, dest, len);
return 0;
}
int main(int argc, char* argv[])
{
char devName[16] = {0};
if (argc > 1)
strncpy(devName, argv[1], sizeof(devName));
else
strncpy(devName, "/dev/sdc", sizeof(devName));
int fd = open(devName, O_RDONLY);
if(fd>=0)
{
__u8 serial[MAX_RAID_SERIAL_LEN];
memset(serial, 0, MAX_RAID_SERIAL_LEN);
int err = read_serial(fd, devName, serial);
if(err==0)
{
printf("%s:[%s]\n", devName, (char*)serial);
}
}
close(fd);
}
以上代码通过修改其它文章中的代码 ,在el5 x86下实测可编译。