Sun, 16 Dec 2012 12:37:59
Harddrive Serial Number
Some code to identify the root drive and get the SCSI serial number from it.
Works on most common single disk filesystem architectures, including LVM.
Toggle View Code
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <fcntl.h>
#include <scsi/scsi.h>
#include <scsi/sg.h>
#include <sys/ioctl.h>
char *trim(char *s) {
int i = 0;
int j = strlen(s) - 1;
int k = 0;
while(isspace(s[i]) && s[i] != '\0') {
i++;
}
while(isspace(s[j]) && s[j] > 0) {
j--;
}
while( i < j ) {
s[k++] = s[i++];
}
s[k] = '\0';
return s;
}
void hddid(char *device) {
int fd;
unsigned char inq_cmd[] = {INQUIRY, 1, 0x80, 0, 255, 0};
unsigned char sense[32];
unsigned char scsi_serial[255];
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 = scsi_serial;
io_hdr.dxfer_len = 255;
io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
io_hdr.sbp = sense;
io_hdr.mx_sb_len = sizeof(sense);
io_hdr.timeout = 5000;
fd = open(device, O_RDONLY | O_NONBLOCK);
if(fd) {
if(ioctl(fd, SG_IO, &io_hdr) == 0) {
fprintf(stdout, "HD Serial Number [%s]\n", trim((char *)&scsi_serial[4]));
}
}
}
char *get_root_device() {
struct stat root_stat;
char line[512];
char *s_ptr;
char *hd_device = NULL;
FILE *partitions;
if(stat("/", &root_stat) == -1) {
fprintf(stderr, "Did not get stat\n");
} else {
printf("Got stat major [%d] minor [%d]\n", major(root_stat.st_dev), minor(root_stat.st_dev));
partitions = fopen("/proc/partitions", "ro");
while(fgets(line, sizeof(line), partitions) != NULL) {
s_ptr = trim(line);
char *major;
char *minor;
char *size;
char *device;
if((major = strtok(s_ptr, " ")) == NULL )
continue;
if((minor = strtok(NULL, " ")) == NULL )
continue;
if((size = strtok(NULL, " ")) == NULL )
continue;
if((device = strtok(NULL, " ")) == NULL )
continue;
if(major(root_stat.st_dev) == atoi(major) && minor(root_stat.st_dev) == atoi(minor)) {
hd_device = (char *)malloc(strlen(device) + 6);
*hd_device = '\0';
strncat(hd_device, "/dev/", 5);
strncat(hd_device, device, strlen(device));
break;
}
}
fclose(partitions);
}
return hd_device;
}
int main() {
char *foo = get_root_device();
if(foo != NULL) {
hddid(foo);
} else {
fprintf(stdout, "Couldn't Identify Root Harddisk\n");
}
free(foo);
return 0;
}