Get HDD and USB Stick Size and Manufacturer name

I need to get from C or from a script info for hard drives and usb sticks.

I get installed disks with:
Code:
sysctl kern.disks

Then for a hard drive is simple:
Code:
egrep ad6: /var/run/dmesg.boot | head -n1

I would get:
Code:
ad6: 152627MB <WDC WD1600JS-22NCB1 10.02E02> at ata3-master UDMA100 SATA 3Gb/s

Here I have all info I need.

The problem arise when I use usb sticks or hot swapable hard drives.
If I connect for example a 2G USB stick and then I remove it and I connect a 8G USB stick I will have two entries with da0 name, and knowing that my devices is da0 does not help because I don't know in /var/run/dmesg.boot which of them (the 2G one or the 8G one) is installed.

Also I am using head -n 1 for hard drives but for usb sticks the sizeinfo is on third line:
Code:
da0: <Generic USB Flash Disk 0.00> Removable Direct Access SCSI-2 device 
da0: 1.000MB/s transfers
da0: 1927MB (3948543 512 byte sectors: 255H 63S/T 245C)

Also da0 could be a SCSI drive in which case rules from hard drives applies (info on first line, not third).

So is there a way to know drive manufacturer/USB String-manufacturer by using only drive name that will apply to: IDE/SATA drives, SCSI/SAS drives and usb flashes?
 
overmind said:
I would need drive size (not a particular partition size) and manufacturer name.

You can calculate drive size via libgeom(3), I have no clue how to extract manufacturer information from a device using userland app other than parsing dmesg.
 
file(1) will show device size:
Code:
# file -s /dev/ada0
/dev/ada0: x86 boot sector; partition 1: ID=0xa5, active, starthead 1, startsector 63, 1953520002 sectors, code offset 0x31

If you can figure out how to tell that /dev/da0 is a USB device, and which one, usbconfig(8) will show the manufacturer:
Code:
# usbconfig -d 1.2 dump_device_desc | grep iManufacturer
  iManufacturer = 0x0001  <Logitech>

camcontrol(8) might do that, too.
 
I took a look at SCSI API documentation and it seem that vendor information can be extracted with INQUIRY command on all SCSI media (including USB disks). And the only way to issue it from userland on FreeBSD is by using the CAM interface. So here is a small piece of code that will display size and vendor info of a SCSI drive:

Code:
#include <sys/types.h>
#include <sys/disk.h>

#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <string.h>

#include <camlib.h>

int main(int argc, char **argv){
	struct cam_device *cam_dev;
	off_t capacity;
	char name[30];
	
	int fd, unit;
	char *dev_path;
	
	if(argc != 2)
		return 1;
		
	memset(name, 0, sizeof(name));
		
	asprintf(&dev_path, "/dev/%s", argv[1]);
	assert(dev_path != NULL);
		
	assert((fd = open(dev_path, O_RDONLY)) > 0);	
	assert(ioctl(fd, DIOCGMEDIASIZE, &capacity) != -1);
	capacity = capacity / (1000 * 1000);
	
	close(fd);
	
	assert(cam_get_device(argv[1], name, sizeof(name), &unit) != -1);	
	assert(
	(cam_dev = cam_open_spec_device(name, unit, O_RDWR, NULL)) != NULL
	);
	
	printf("%s [%s]: size = %dMb(decimal)\n", 
	argv[1], cam_dev->inq_data.vendor, capacity);
	
	cam_close_device(cam_dev);
	
	return 0;
}

Sample output for my Nokia phone:
Code:
# ./udrive_info da0
da0 [Nokia   N8-00           1.0 ]: size = 15351Mb(decimal)
 
@expl - Thank you, your solution is what I needed. I will use yours for SCSI/SAS, USB and I will take from dmesg for IDE/SATA.

It's possibly the same thing for IDE/SATA drives, of course with other system functions?
 
Back
Top