Home | History | Annotate | Line # | Download | only in raidframe
rf_disks.c revision 1.1
      1 /*	$NetBSD: rf_disks.c,v 1.1 1998/11/13 04:20:29 oster Exp $	*/
      2 /*
      3  * Copyright (c) 1995 Carnegie-Mellon University.
      4  * All rights reserved.
      5  *
      6  * Author: Mark Holland
      7  *
      8  * Permission to use, copy, modify and distribute this software and
      9  * its documentation is hereby granted, provided that both the copyright
     10  * notice and this permission notice appear in all copies of the
     11  * software, derivative works or modified versions, and any portions
     12  * thereof, and that both notices appear in supporting documentation.
     13  *
     14  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
     15  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND
     16  * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
     17  *
     18  * Carnegie Mellon requests users of this software to return to
     19  *
     20  *  Software Distribution Coordinator  or  Software.Distribution (at) CS.CMU.EDU
     21  *  School of Computer Science
     22  *  Carnegie Mellon University
     23  *  Pittsburgh PA 15213-3890
     24  *
     25  * any improvements or extensions that they make and grant Carnegie the
     26  * rights to redistribute these changes.
     27  */
     28 
     29 /***************************************************************
     30  * rf_disks.c -- code to perform operations on the actual disks
     31  ***************************************************************/
     32 
     33 /* :
     34  * Log: rf_disks.c,v
     35  * Revision 1.32  1996/07/27 18:40:24  jimz
     36  * cleanup sweep
     37  *
     38  * Revision 1.31  1996/07/22  19:52:16  jimz
     39  * switched node params to RF_DagParam_t, a union of
     40  * a 64-bit int and a void *, for better portability
     41  * attempted hpux port, but failed partway through for
     42  * lack of a single C compiler capable of compiling all
     43  * source files
     44  *
     45  * Revision 1.30  1996/07/19  16:11:21  jimz
     46  * pass devname to DoReadCapacity
     47  *
     48  * Revision 1.29  1996/07/18  22:57:14  jimz
     49  * port simulator to AIX
     50  *
     51  * Revision 1.28  1996/07/10  22:28:38  jimz
     52  * get rid of obsolete row statuses (dead,degraded2)
     53  *
     54  * Revision 1.27  1996/06/10  12:06:14  jimz
     55  * don't do any SCSI op stuff in simulator at all
     56  *
     57  * Revision 1.26  1996/06/10  11:55:47  jimz
     58  * Straightened out some per-array/not-per-array distinctions, fixed
     59  * a couple bugs related to confusion. Added shutdown lists. Removed
     60  * layout shutdown function (now subsumed by shutdown lists).
     61  *
     62  * Revision 1.25  1996/06/09  02:36:46  jimz
     63  * lots of little crufty cleanup- fixup whitespace
     64  * issues, comment #ifdefs, improve typing in some
     65  * places (esp size-related)
     66  *
     67  * Revision 1.24  1996/06/07  21:33:04  jimz
     68  * begin using consistent types for sector numbers,
     69  * stripe numbers, row+col numbers, recon unit numbers
     70  *
     71  * Revision 1.23  1996/06/03  23:28:26  jimz
     72  * more bugfixes
     73  * check in tree to sync for IPDS runs with current bugfixes
     74  * there still may be a problem with threads in the script test
     75  * getting I/Os stuck- not trivially reproducible (runs ~50 times
     76  * in a row without getting stuck)
     77  *
     78  * Revision 1.22  1996/06/02  17:31:48  jimz
     79  * Moved a lot of global stuff into array structure, where it belongs.
     80  * Fixed up paritylogging, pss modules in this manner. Some general
     81  * code cleanup. Removed lots of dead code, some dead files.
     82  *
     83  * Revision 1.21  1996/05/30  23:22:16  jimz
     84  * bugfixes of serialization, timing problems
     85  * more cleanup
     86  *
     87  * Revision 1.20  1996/05/30  11:29:41  jimz
     88  * Numerous bug fixes. Stripe lock release code disagreed with the taking code
     89  * about when stripes should be locked (I made it consistent: no parity, no lock)
     90  * There was a lot of extra serialization of I/Os which I've removed- a lot of
     91  * it was to calculate values for the cache code, which is no longer with us.
     92  * More types, function, macro cleanup. Added code to properly quiesce the array
     93  * on shutdown. Made a lot of stuff array-specific which was (bogusly) general
     94  * before. Fixed memory allocation, freeing bugs.
     95  *
     96  * Revision 1.19  1996/05/27  18:56:37  jimz
     97  * more code cleanup
     98  * better typing
     99  * compiles in all 3 environments
    100  *
    101  * Revision 1.18  1996/05/24  22:17:04  jimz
    102  * continue code + namespace cleanup
    103  * typed a bunch of flags
    104  *
    105  * Revision 1.17  1996/05/24  01:59:45  jimz
    106  * another checkpoint in code cleanup for release
    107  * time to sync kernel tree
    108  *
    109  * Revision 1.16  1996/05/23  21:46:35  jimz
    110  * checkpoint in code cleanup (release prep)
    111  * lots of types, function names have been fixed
    112  *
    113  * Revision 1.15  1996/05/23  00:33:23  jimz
    114  * code cleanup: move all debug decls to rf_options.c, all extern
    115  * debug decls to rf_options.h, all debug vars preceded by rf_
    116  *
    117  * Revision 1.14  1996/05/18  19:51:34  jimz
    118  * major code cleanup- fix syntax, make some types consistent,
    119  * add prototypes, clean out dead code, et cetera
    120  *
    121  * Revision 1.13  1996/05/02  14:57:43  jimz
    122  * initialize sectorMask
    123  *
    124  * Revision 1.12  1995/12/01  15:57:04  root
    125  * added copyright info
    126  *
    127  */
    128 
    129 #include "rf_types.h"
    130 #include "rf_raid.h"
    131 #include "rf_alloclist.h"
    132 #include "rf_utils.h"
    133 #include "rf_configure.h"
    134 #include "rf_general.h"
    135 #if !defined(__NetBSD__)
    136 #include "rf_camlayer.h"
    137 #endif
    138 #include "rf_options.h"
    139 #include "rf_sys.h"
    140 
    141 #if defined(__NetBSD__) && defined(_KERNEL)
    142 #include <sys/types.h>
    143 #include <sys/param.h>
    144 #include <sys/systm.h>
    145 #include <sys/proc.h>
    146 #include <sys/ioctl.h>
    147 #include <sys/fcntl.h>
    148 #include <sys/vnode.h>
    149 
    150 int raidlookup __P((char *, struct proc *p, struct vnode **));
    151 #endif
    152 
    153 #ifdef SIMULATE
    154 static char disk_db_file_name[120], disk_type_name[120];
    155 static double init_offset;
    156 #endif /* SIMULATE  */
    157 
    158 #define DPRINTF6(a,b,c,d,e,f) if (rf_diskDebug) printf(a,b,c,d,e,f)
    159 #define DPRINTF7(a,b,c,d,e,f,g) if (rf_diskDebug) printf(a,b,c,d,e,f,g)
    160 
    161 #include "rf_ccmn.h"
    162 
    163 /****************************************************************************************
    164  *
    165  * initialize the disks comprising the array
    166  *
    167  * We want the spare disks to have regular row,col numbers so that we can easily
    168  * substitue a spare for a failed disk.  But, the driver code assumes throughout
    169  * that the array contains numRow by numCol _non-spare_ disks, so it's not clear
    170  * how to fit in the spares.  This is an unfortunate holdover from raidSim.  The
    171  * quick and dirty fix is to make row zero bigger than the rest, and put all the
    172  * spares in it.  This probably needs to get changed eventually.
    173  *
    174  ***************************************************************************************/
    175 int rf_ConfigureDisks(
    176   RF_ShutdownList_t  **listp,
    177   RF_Raid_t           *raidPtr,
    178   RF_Config_t         *cfgPtr)
    179 {
    180   RF_RaidDisk_t **disks;
    181   RF_SectorCount_t min_numblks = (RF_SectorCount_t)0x7FFFFFFFFFFFLL;
    182   RF_RowCol_t r, c;
    183   int bs, ret;
    184   unsigned i, count, foundone=0, numFailuresThisRow;
    185   RF_DiskOp_t *rdcap_op = NULL, *tur_op = NULL;
    186   int num_rows_done,num_cols_done;
    187 
    188 #if defined(__NetBSD__) && defined(_KERNEL)
    189 	struct proc *proc = 0;
    190 #endif
    191 #ifndef SIMULATE
    192 #ifndef __NetBSD__
    193   ret = rf_SCSI_AllocReadCapacity(&rdcap_op);
    194   if (ret)
    195     goto fail;
    196   ret = rf_SCSI_AllocTUR(&tur_op);
    197   if (ret)
    198     goto fail;
    199 #endif /* !__NetBSD__ */
    200 #endif /* !SIMULATE */
    201 
    202   num_rows_done = 0;
    203   num_cols_done = 0;
    204 
    205 
    206   RF_CallocAndAdd(disks, raidPtr->numRow, sizeof(RF_RaidDisk_t *), (RF_RaidDisk_t **), raidPtr->cleanupList);
    207   if (disks == NULL) {
    208     ret = ENOMEM;
    209     goto fail;
    210   }
    211   raidPtr->Disks = disks;
    212 
    213 #if defined(__NetBSD__) && defined(_KERNEL)
    214 
    215   proc = raidPtr->proc; /* Blah XXX */
    216 
    217   /* get space for the device-specific stuff... */
    218   RF_CallocAndAdd(raidPtr->raid_cinfo, raidPtr->numRow,
    219 		  sizeof(struct raidcinfo *), (struct raidcinfo **),
    220 		  raidPtr->cleanupList);
    221   if (raidPtr->raid_cinfo == NULL) {
    222 	  ret = ENOMEM;
    223 	  goto fail;
    224   }
    225 #endif
    226 
    227   for (r=0; r<raidPtr->numRow; r++) {
    228     numFailuresThisRow = 0;
    229     RF_CallocAndAdd(disks[r], raidPtr->numCol + ((r==0) ? raidPtr->numSpare : 0), sizeof(RF_RaidDisk_t), (RF_RaidDisk_t *), raidPtr->cleanupList);
    230     if (disks[r] == NULL) {
    231       ret = ENOMEM;
    232       goto fail;
    233     }
    234 
    235     /* get more space for device specific stuff.. */
    236     RF_CallocAndAdd(raidPtr->raid_cinfo[r],
    237 		    raidPtr->numCol + ((r==0) ? raidPtr->numSpare : 0),
    238 		    sizeof(struct raidcinfo), (struct raidcinfo *),
    239 		    raidPtr->cleanupList);
    240     if (raidPtr->raid_cinfo[r] == NULL) {
    241       ret = ENOMEM;
    242       goto fail;
    243     }
    244 
    245 
    246     for (c=0; c<raidPtr->numCol; c++) {
    247       ret = rf_ConfigureDisk(raidPtr,&cfgPtr->devnames[r][c][0],
    248 			     &disks[r][c], rdcap_op, tur_op,
    249 			     cfgPtr->devs[r][c],r,c);
    250       if (ret)
    251         goto fail;
    252       if (disks[r][c].status != rf_ds_optimal) {
    253         numFailuresThisRow++;
    254       }
    255       else {
    256         if (disks[r][c].numBlocks < min_numblks)
    257           min_numblks = disks[r][c].numBlocks;
    258         DPRINTF7("Disk at row %d col %d: dev %s numBlocks %ld blockSize %d (%ld MB)\n",
    259           r,c,disks[r][c].devname,
    260 		 (long int) disks[r][c].numBlocks,
    261 		 disks[r][c].blockSize,
    262 		 (long int) disks[r][c].numBlocks * disks[r][c].blockSize / 1024 / 1024);
    263       }
    264       num_cols_done++;
    265     }
    266     /* XXX fix for n-fault tolerant */
    267     if (numFailuresThisRow > 0)
    268       raidPtr->status[r] = rf_rs_degraded;
    269     num_rows_done++;
    270   }
    271 #ifndef SIMULATE
    272 #if defined(__NetBSD__) && defined(_KERNEL)
    273   /* we do nothing */
    274 #else
    275   rf_SCSI_FreeDiskOp(rdcap_op, 1); rdcap_op = NULL;
    276   rf_SCSI_FreeDiskOp(tur_op, 0);   tur_op   = NULL;
    277 #endif
    278 #endif /* !SIMULATE */
    279   /* all disks must be the same size & have the same block size, bs must be a power of 2 */
    280   bs = 0;
    281   for (foundone=r=0; !foundone && r<raidPtr->numRow; r++) {
    282     for (c=0; !foundone && c<raidPtr->numCol; c++) {
    283       if (disks[r][c].status == rf_ds_optimal) {
    284         bs = disks[r][c].blockSize;
    285         foundone = 1;
    286       }
    287     }
    288   }
    289   if (!foundone) {
    290     RF_ERRORMSG("RAIDFRAME: Did not find any live disks in the array.\n");
    291     ret = EINVAL;
    292     goto fail;
    293   }
    294   for (count=0,i=1; i; i<<=1) if (bs & i)
    295     count++;
    296   if (count != 1) {
    297     RF_ERRORMSG1("Error: block size on disks (%d) must be a power of 2\n",bs);
    298     ret = EINVAL;
    299     goto fail;
    300   }
    301   for (r=0; r<raidPtr->numRow; r++) {
    302     for (c=0; c<raidPtr->numCol; c++) {
    303       if (disks[r][c].status == rf_ds_optimal) {
    304 	if (disks[r][c].blockSize != bs) {
    305 	  RF_ERRORMSG2("Error: block size of disk at r %d c %d different from disk at r 0 c 0\n",r,c);
    306 	  ret = EINVAL;
    307 	  goto fail;
    308 	}
    309 	if (disks[r][c].numBlocks != min_numblks) {
    310 	  RF_ERRORMSG3("WARNING: truncating disk at r %d c %d to %d blocks\n",
    311 		       r,c,(int) min_numblks);
    312 	  disks[r][c].numBlocks = min_numblks;
    313 	}
    314       }
    315     }
    316   }
    317 
    318   raidPtr->sectorsPerDisk = min_numblks;
    319   raidPtr->logBytesPerSector = ffs(bs) - 1;
    320   raidPtr->bytesPerSector = bs;
    321   raidPtr->sectorMask = bs-1;
    322   return(0);
    323 
    324 fail:
    325 
    326 #ifndef SIMULATE
    327 #if defined(__NetBSD__) && defined(_KERNEL)
    328 
    329   for(r=0;r<raidPtr->numRow;r++) {
    330 	  for(c=0;c<raidPtr->numCol;c++) {
    331 		  /* Cleanup.. */
    332 #ifdef DEBUG
    333 		  printf("Cleaning up row: %d col: %d\n",r,c);
    334 #endif
    335 		  if (raidPtr->raid_cinfo[r][c].ci_vp) {
    336 			  (void)vn_close(raidPtr->raid_cinfo[r][c].ci_vp,
    337 					 FREAD|FWRITE, proc->p_ucred, proc);
    338 		  }
    339 	  }
    340   }
    341   /* Space allocated for raid_vpp will get cleaned up at some other point */
    342   /* XXX Need more #ifdefs in the above... */
    343 
    344 #else
    345 
    346   if (rdcap_op) rf_SCSI_FreeDiskOp(rdcap_op, 1);
    347   if (tur_op)   rf_SCSI_FreeDiskOp(tur_op, 0);
    348 
    349 #endif
    350 #endif /* !SIMULATE */
    351   return(ret);
    352 }
    353 
    354 
    355 /****************************************************************************************
    356  * set up the data structures describing the spare disks in the array
    357  * recall from the above comment that the spare disk descriptors are stored
    358  * in row zero, which is specially expanded to hold them.
    359  ***************************************************************************************/
    360 int rf_ConfigureSpareDisks(
    361   RF_ShutdownList_t  **listp,
    362   RF_Raid_t           *raidPtr,
    363   RF_Config_t         *cfgPtr)
    364 {
    365   char buf[256];
    366   int i, ret;
    367   RF_DiskOp_t *rdcap_op = NULL, *tur_op = NULL;
    368   unsigned bs;
    369   RF_RaidDisk_t *disks;
    370   int num_spares_done;
    371 
    372 #if defined(__NetBSD__) && defined(_KERNEL)
    373 	struct proc *proc;
    374 #endif
    375 
    376 #ifndef SIMULATE
    377 #ifndef __NetBSD__
    378   ret = rf_SCSI_AllocReadCapacity(&rdcap_op);
    379   if (ret)
    380     goto fail;
    381   ret = rf_SCSI_AllocTUR(&tur_op);
    382   if (ret)
    383     goto fail;
    384 #endif /* !__NetBSD__ */
    385 #endif /* !SIMULATE */
    386 
    387   num_spares_done = 0;
    388 
    389 #if defined(__NetBSD__) && defined(_KERNEL)
    390   proc = raidPtr->proc;
    391   /* The space for the spares should have already been
    392      allocated by ConfigureDisks() */
    393 #endif
    394 
    395   disks = &raidPtr->Disks[0][raidPtr->numCol];
    396   for (i=0; i<raidPtr->numSpare; i++) {
    397     ret = rf_ConfigureDisk(raidPtr,&cfgPtr->spare_names[i][0],
    398 			   &disks[i], rdcap_op, tur_op,
    399 			   cfgPtr->spare_devs[i],0,raidPtr->numCol+i);
    400     if (ret)
    401       goto fail;
    402     if (disks[i].status != rf_ds_optimal) {
    403       RF_ERRORMSG1("Warning: spare disk %s failed TUR\n",buf);
    404     } else {
    405       disks[i].status = rf_ds_spare;      /* change status to spare */
    406       DPRINTF6("Spare Disk %d: dev %s numBlocks %ld blockSize %d (%ld MB)\n",i,
    407 	       disks[i].devname,
    408 	       (long int) disks[i].numBlocks,disks[i].blockSize,
    409 	       (long int) disks[i].numBlocks * disks[i].blockSize / 1024 / 1024);
    410     }
    411     num_spares_done++;
    412   }
    413 #ifndef SIMULATE
    414 #if defined(__NetBSD__) && (_KERNEL)
    415 
    416 #else
    417   rf_SCSI_FreeDiskOp(rdcap_op, 1); rdcap_op = NULL;
    418   rf_SCSI_FreeDiskOp(tur_op, 0);   tur_op   = NULL;
    419 #endif
    420 #endif /* !SIMULATE */
    421 
    422   /* check sizes and block sizes on spare disks */
    423   bs = 1 << raidPtr->logBytesPerSector;
    424   for (i=0; i<raidPtr->numSpare; i++) {
    425     if (disks[i].blockSize != bs) {
    426       RF_ERRORMSG3("Block size of %d on spare disk %s is not the same as on other disks (%d)\n",disks[i].blockSize, disks[i].devname, bs);
    427       ret = EINVAL;
    428       goto fail;
    429     }
    430     if (disks[i].numBlocks < raidPtr->sectorsPerDisk) {
    431 	    RF_ERRORMSG3("Spare disk %s (%d blocks) is too small to serve as a spare (need %ld blocks)\n",
    432 		disks[i].devname, disks[i].blockSize, (long int)raidPtr->sectorsPerDisk);
    433       ret = EINVAL;
    434       goto fail;
    435     } else if (disks[i].numBlocks > raidPtr->sectorsPerDisk) {
    436 	    RF_ERRORMSG2("Warning: truncating spare disk %s to %ld blocks\n",disks[i].devname, (long int) raidPtr->sectorsPerDisk);
    437 
    438       disks[i].numBlocks = raidPtr->sectorsPerDisk;
    439     }
    440   }
    441 
    442   return(0);
    443 
    444 fail:
    445 #ifndef SIMULATE
    446 #if defined(__NetBSD__) && defined(_KERNEL)
    447 
    448   for(i=0;i<raidPtr->numSpare;i++) {
    449 	  /* Cleanup.. */
    450 #ifdef DEBUG
    451 	  printf("Cleaning up spare: %d\n",i);
    452 #endif
    453 	  if (raidPtr->raid_cinfo[0][raidPtr->numCol+i].ci_vp) {
    454 		  (void)vn_close(raidPtr->raid_cinfo[0][raidPtr->numCol+i].ci_vp,
    455 				 FREAD|FWRITE, proc->p_ucred, proc);
    456 	  }
    457   }
    458 
    459 #else
    460 
    461   if (rdcap_op) rf_SCSI_FreeDiskOp(rdcap_op, 1);
    462   if (tur_op)   rf_SCSI_FreeDiskOp(tur_op, 0);
    463 
    464 #endif
    465 
    466 #endif /* !SIMULATE */
    467   return(ret);
    468 }
    469 
    470 
    471 
    472 /* configure a single disk in the array */
    473 int rf_ConfigureDisk(raidPtr, buf, diskPtr, rdcap_op, tur_op, dev, row, col)
    474   RF_Raid_t      *raidPtr;  /* We need this down here too!! GO */
    475   char           *buf;
    476   RF_RaidDisk_t  *diskPtr;
    477   RF_DiskOp_t    *rdcap_op;
    478   RF_DiskOp_t    *tur_op;
    479   dev_t           dev;      /* device number used only in kernel */
    480   RF_RowCol_t     row;
    481   RF_RowCol_t     col;
    482 {
    483   char *p;
    484 #ifdef SIMULATE
    485   double	init_offset;
    486 #else /* SIMULATE  */
    487 #if defined(__NetBSD__) && defined(_KERNEL)
    488   int retcode;
    489 #else
    490   int busid, targid, lun, retcode;
    491 #endif
    492 #endif /* SIMULATE  */
    493 
    494 #if defined(__NetBSD__) && defined(_KERNEL)
    495 	struct partinfo dpart;
    496 	struct vnode *vp;
    497 	struct vattr va;
    498 	struct proc *proc;
    499 	int error;
    500 #endif
    501 
    502 retcode = 0;
    503   p = rf_find_non_white(buf);
    504   if (p[strlen(p)-1] == '\n') {
    505     /* strip off the newline */
    506     p[strlen(p)-1] = '\0';
    507   }
    508   (void) strcpy(diskPtr->devname, p);
    509 
    510 #ifdef SIMULATE
    511 
    512   init_offset = 0.0;
    513   rf_InitDisk(&diskPtr->diskState, disk_db_file_name,diskPtr->devname,0,0,init_offset,row,col);
    514   rf_GeometryDoReadCapacity(&diskPtr->diskState, &diskPtr->numBlocks, &diskPtr->blockSize);
    515   diskPtr->numBlocks = diskPtr->numBlocks * rf_sizePercentage / 100;
    516 
    517   /* we allow the user to specify that only a fraction of the disks should be used
    518    * this is just for debug:  it speeds up the parity scan
    519    */
    520 
    521 #else /* SIMULATE */
    522 #ifndef __NetBSD__
    523   /* get bus, target, lun */
    524   retcode = rf_extract_ids(p, &busid, &targid, &lun);
    525   if (retcode)
    526     return(retcode);
    527 
    528   /* required in kernel, nop at user level */
    529   retcode = rf_SCSI_OpenUnit(dev);
    530   if (retcode)
    531     return(retcode);
    532 
    533   diskPtr->dev = dev;
    534   if (rf_SCSI_DoTUR(tur_op, (u_char)busid, (u_char)targid, (u_char)lun, dev)) {
    535     RF_ERRORMSG1("Disk %s failed TUR.  Marked as dead.\n",diskPtr->devname);
    536     diskPtr->status = rf_ds_failed;
    537   } else {
    538     diskPtr->status = rf_ds_optimal;
    539     retcode = rf_SCSI_DoReadCapacity(raidPtr,rdcap_op, busid, targid, lun, dev,
    540       &diskPtr->numBlocks, &diskPtr->blockSize, diskPtr->devname);
    541     if (retcode)
    542       return(retcode);
    543 
    544     /* we allow the user to specify that only a fraction of the disks should be used
    545      * this is just for debug:  it speeds up the parity scan
    546      */
    547     diskPtr->numBlocks = diskPtr->numBlocks * rf_sizePercentage / 100;
    548   }
    549 #endif
    550 #if defined(__NetBSD__) && defined(_KERNEL)
    551 
    552   proc = raidPtr->proc;  /* XXX Yes, this is not nice.. */
    553 
    554   /* Let's start by claiming the component is fine and well... */
    555   /* XXX not the case if the disk is toast.. */
    556   diskPtr->status = rf_ds_optimal;
    557 
    558 
    559   raidPtr->raid_cinfo[row][col].ci_vp = NULL;
    560   raidPtr->raid_cinfo[row][col].ci_dev = NULL;
    561 
    562   error = raidlookup(diskPtr->devname, proc, &vp);
    563   if (error) {
    564 	  printf("raidlookup on device: %s failed!\n",diskPtr->devname);
    565 	  if (error == ENXIO) {
    566 		  /* XXX the component isn't there... must be dead :-( */
    567 		  diskPtr->status = rf_ds_failed;
    568 	  } else {
    569 		  return(error);
    570 	  }
    571   }
    572 
    573   if (diskPtr->status == rf_ds_optimal) {
    574 
    575 	  if ((error = VOP_GETATTR(vp, &va, proc->p_ucred, proc)) != 0) {
    576 		  return(error);
    577 	  }
    578 
    579 	  error = VOP_IOCTL(vp, DIOCGPART, (caddr_t)&dpart,
    580 			    FREAD, proc->p_ucred, proc);
    581 	  if (error) {
    582 		  return(error);
    583 	  }
    584 
    585 
    586 	  diskPtr->blockSize = dpart.disklab->d_secsize;
    587 
    588 	  diskPtr->numBlocks = dpart.part->p_size - rf_protectedSectors;
    589 
    590 	  raidPtr->raid_cinfo[row][col].ci_vp = vp;
    591 	  raidPtr->raid_cinfo[row][col].ci_dev = va.va_rdev;
    592 
    593 #if 0
    594 	  diskPtr->dev = dev;
    595 #endif
    596 
    597 	  diskPtr->dev = va.va_rdev; /* XXX or the above? */
    598 
    599 	  /* we allow the user to specify that only a fraction of the disks should be used
    600 	   * this is just for debug:  it speeds up the parity scan
    601 	   */
    602 	  diskPtr->numBlocks = diskPtr->numBlocks * rf_sizePercentage / 100;
    603 
    604   }
    605 
    606 #endif /* !__NetBSD__ */
    607 #endif /* SIMULATE */
    608 
    609   return(0);
    610 }
    611 
    612 #ifdef SIMULATE
    613 
    614 void rf_default_disk_names()
    615 {
    616     sprintf(disk_db_file_name,"disk.db");
    617     sprintf(disk_type_name,"HP2247");
    618 }
    619 
    620 void rf_set_disk_db_name(s)
    621  char  *s;
    622 {
    623     strcpy(disk_db_file_name,s);
    624 }
    625 
    626 void rf_set_disk_type_name(s)
    627  char  *s;
    628 {
    629     strcpy(disk_type_name,s);
    630 }
    631 
    632 #endif /* SIMULATE */
    633