ianhogg@cs.umn.edu (Ian J. Hogg) (02/12/91)
Here it is, the wonderful scsi_info program that creates disktab entries for you It has only been tested on Imprimis disk drives. I don't know how well it works for other vendors' drives. I believe that it core dumped when tryin to get info from whatever HP's first 300 MB scsi drive was. Anyways use it to your hearts content, and I hope it helps others as much as it did me. If anyone has mods or enhancements let me send me mail. If someone else wants to be a sort of official keeper of this program, let me know. I would but since I switched jobs I don't have access to any HP's. ====================== cut here ========================================= /***************************************************************************** This program was written by Matt Endres, Imprimis Technology. usage: scsi_info special name mbytes where: special is the raw device file for the scsi device for which the information is to be displayed name is a name to be used for the disktab entry mbytes is the number of MBytes to be used as swap space on the device Example: To create a disktab entry for a SABRE V disk drive whose device file is located in the device directory /dev/rdsk/1s0 with 50 Mbytes of swap, the command line is: scsi_info /dev/rdsk/1s0 SABRE_V 50 ****************************************************************************/ #include <sys/types.h> #include <sys/scsi.h> #include <sys/ioctl.h> #include <fcntl.h> struct inquiry i_data; struct capacity c_data; char scsi_vendor[9]; char scsi_product[17]; int num_cylinders; int num_heads; int num_usable_sectors; int alt_sect,tracks_zone,sectors_track; int swap; int scsi_dev; char *entry_name; unsigned char geometry_data[100]; unsigned char dad_form_data[100]; char *scsi_device_name; main(argc,argv) int argc; char *argv[]; { if (argc < 4) { printf("Usage: scsi_info special disktab_name swap_size\n"); exit(1); } scsi_device_name=argv[1]; scsi_dev=open(scsi_device_name,O_RDONLY); if (scsi_dev == -1) { printf("Unable to open %s\n",argv[1]); exit(1); } sscanf(argv[3],"%d",&swap); entry_name=argv[2]; print_ids(); print_geometry(); print_disktab_entry(); close(scsi_dev); } /******************************************************************** print_ids This procedure will issue an inquiry command to the opened scsi device (raw device must be used) and print out the returned information. This information is not needed for the disktab file. ********************************************************************/ print_ids() { int x; ioctl(scsi_dev,SIOC_INQUIRY,&i_data); for(x=0;x<8;x++) scsi_vendor[x]=i_data.vendor_id[x]; scsi_vendor[8]='\0'; for(x=0;x<16;x++) scsi_product[x]=i_data.product_id[x]; scsi_product[16]='\0'; printf("\nInformation for device %s\n",scsi_device_name); printf("\nVendor = %s\n",scsi_vendor); printf("Product type = %s\n",scsi_product); } /***************************************************************** print_geometry: This procedure will issue a mode sense geometry command, a mode sense format command, and a capacity command to the scsi device. The returned data will be printed out, this data will be used to computer the disktab entry. *******************************************************************/ print_geometry() { int offset; ioctl(scsi_dev,SIOC_MODE_SENSE_GEOMETRY,geometry_data); ioctl(scsi_dev,SIOC_MODE_SENSE_FORMAT,dad_form_data); ioctl(scsi_dev,SIOC_CAPACITY,&c_data); for(offset=0;geometry_data[offset] != 0x84;offset++); num_cylinders=(geometry_data[offset + 2]<<12)+(geometry_data[offset + 3]<<8)+geometry_data[offset + 4]; num_heads=geometry_data[offset + 5]; alt_sect=(dad_form_data[16]<<8) + dad_form_data[17]; tracks_zone=(dad_form_data[14]<<8) + dad_form_data[15]; sectors_track=(dad_form_data[22]<<8) + dad_form_data[23]; num_usable_sectors=(sectors_track -(1 / (tracks_zone * alt_sect)))/(1024 / c_data.blksz); printf("Number of total blocks = %d\n",c_data.lba); printf("Block Size = %d\n",c_data.blksz); printf("Number of Cylinders = %d\n",num_cylinders); printf("Number of Heads = %d\n",num_heads); printf("Number of 1K Sectors/Track = %d\n",num_usable_sectors); } /******************************************************************** print_disktab_entry: This procedure will calculate the disktab entry and print it. The entry is calculated in the following manner: The number of cylinders is equal to the total number of cylinders minus the number of cylinders used for swap space. The number of usable sectors is the number of 1 Kbyte sectors per track. This may cause some sectors to be unused if the number of sectors times the block size is not divisible by 1024. The s0 entry in the disktab file is the number of usable sectors times the number of tracks (heads) times the number of cylinders which are not used for swap space. The numbers printed out may not be the same as listed in the disk drive manuals because scsi devices reserve some sectors and some cylinders for alternates because of flaws on the disk. *********************************************************************/ print_disktab_entry() { long file_cylinders; double swap_space,file_space; if ((swap * 1024) > (c_data.lba / (1024 / c_data.blksz))) { printf("\n\nSwap size requested is larger than total disk size\n"); printf("Unable to create disktab endtry\n"); exit(2); } file_cylinders=num_cylinders-((swap * 1024)/(num_heads*num_usable_sectors)+1); if (swap==0) swap_space=0; else swap_space=((num_cylinders - file_cylinders) * num_heads * num_usable_sectors); file_space=(file_cylinders * num_heads * num_usable_sectors); file_space=file_space / 1024; swap_space=swap_space / 1024; printf("\nFile System Parameters:\n"); printf(" %1.3f Mbyte(s) swap\n",swap_space); printf(" %1.3f Mbyte(s) usable file space\n",file_space); printf("\n\n\n/etc/disktab entry\n"); printf("\n%s:\\\n",entry_name); printf(" :%d Mbyte(s) Swap:ns#%d:nt#%d:nc#%d:\\\n",swap, num_usable_sectors,num_heads,file_cylinders); printf(" :s0#%d:b0#8192:f0#1024:\\\n",num_usable_sectors * num_heads * file_cylinders); printf(" :se#%d:rm#3600:\n",c_data.blksz); } -- =============================================================================== Ian Hogg ianhogg@cs.umn.edu (612) 225-1401