📄 rf_configure.c
字号:
} c = sscanf(buf,"%d %d %d %c", &aa, &bb, &cc, &cfgPtr->parityConfig); cfgPtr->sectPerSU = (RF_SectorNum_t)aa; cfgPtr->SUsPerPU = (RF_StripeNum_t)bb; cfgPtr->SUsPerRU = (RF_StripeNum_t)cc; if (c != 4) { RF_ERRORMSG("Unable to scan common layout line\n"); retcode = -1; goto out; } lp = rf_GetLayout(cfgPtr->parityConfig); if (lp == NULL) { RF_ERRORMSG1("Unknown parity config '%c'\n", cfgPtr->parityConfig); retcode = -1; goto out; } retcode = lp->MakeLayoutSpecific(fp, cfgPtr, lp->makeLayoutSpecificArg);out: fclose(fp); if (retcode < 0) retcode = errno = EINVAL; else errno = retcode; return(retcode);}/* used in architectures such as RAID0 where there is no layout-specific * information to be passed into the configuration code. */int rf_MakeLayoutSpecificNULL(fp, cfgPtr, ignored) FILE *fp; RF_Config_t *cfgPtr; void *ignored;{ cfgPtr->layoutSpecificSize = 0; cfgPtr->layoutSpecific = NULL; return(0);}int rf_MakeLayoutSpecificDeclustered(configfp, cfgPtr, arg) FILE *configfp; RF_Config_t *cfgPtr; void *arg;{ int b, v, k, r, lambda, norotate, i, val, distSpare; char *cfgBuf, *bdfile, *p, *smname; char buf[256], smbuf[256]; FILE *fp; distSpare = *((int *)arg); /* get the block design file name */ if (rf_get_next_nonblank_line(buf,256,configfp,"Can't find block design file name in config file\n")) return(EINVAL); bdfile = rf_find_non_white(buf); if (bdfile[strlen(bdfile)-1] == '\n') { /* strip newline char */ bdfile[strlen(bdfile)-1] = '\0'; } /* open bd file, check validity of configuration */ if ((fp = fopen(bdfile,"r"))==NULL) { RF_ERRORMSG1("RAID: config error: Can't open layout table file %s\n",bdfile); return(EINVAL); } fgets(buf,256,fp); i = sscanf(buf,"%u %u %u %u %u %u",&b,&v,&k,&r,&lambda,&norotate); if (i == 5) norotate = 0; /* no-rotate flag is optional */ else if (i != 6) { RF_ERRORMSG("Unable to parse header line in block design file\n"); return(EINVAL); } /* set the sparemap directory. In the in-kernel version, there's a daemon * that's responsible for finding the sparemaps */ if (distSpare) { if (rf_get_next_nonblank_line(smbuf,256,configfp,"Can't find sparemap file name in config file\n")) return(EINVAL); smname = rf_find_non_white(smbuf); if (smname[strlen(smname)-1] == '\n') { /* strip newline char */ smname[strlen(smname)-1] = '\0'; } } else { smbuf[0] = '\0'; smname = smbuf; } /* allocate a buffer to hold the configuration info */ cfgPtr->layoutSpecificSize = RF_SPAREMAP_NAME_LEN + 6 * sizeof(int) + b * k; /* can't use RF_Malloc here b/c debugMem module not yet init'd */ cfgBuf = (char *) malloc(cfgPtr->layoutSpecificSize); cfgPtr->layoutSpecific = (void *) cfgBuf; p = cfgBuf; /* install name of sparemap file */ for (i=0; smname[i]; i++) *p++ = smname[i]; /* pad with zeros */ while (i<RF_SPAREMAP_NAME_LEN) { *p++ = '\0'; i++; } /* * fill in the buffer with the block design parameters * and then the block design itself */ *( (int *) p) = b; p += sizeof(int); *( (int *) p) = v; p += sizeof(int); *( (int *) p) = k; p += sizeof(int); *( (int *) p) = r; p += sizeof(int); *( (int *) p) = lambda; p += sizeof(int); *( (int *) p) = norotate; p += sizeof(int); while (fscanf(fp,"%d",&val) == 1) *p++ = (char) val; fclose(fp); if (p - cfgBuf != cfgPtr->layoutSpecificSize) { RF_ERRORMSG2("Size mismatch creating layout specific data: is %d sb %d bytes\n",(p-cfgBuf),6*sizeof(int)+b*k); return(EINVAL); } return(0);}/**************************************************************************** * * utilities * ***************************************************************************//* convert a device file name to a device number */static unsigned int dev_name2num(s) char *s;{ struct stat buf; if (stat(s, &buf) < 0) return(osf_dev_name2num(s)); else return(buf.st_rdev);}/* converts an osf/1 style device name to a device number. We use this * only if the stat of the device file fails. */static unsigned int osf_dev_name2num(s) char *s;{ int num; char part_ch, lun_ch; unsigned int bus, target, lun, part, dev_major; dev_major = RF_SCSI_DISK_MAJOR; if (sscanf(s,"/dev/rrz%d%c", &num, &part_ch) == 2) { bus = num>>3; target = num & 0x7; part = part_ch - 'a'; lun = 0; } else if (sscanf(s,"/dev/rrz%c%d%c", &lun_ch, &num, &part_ch) == 3) { bus = num>>3; target = num & 0x7; part = part_ch - 'a'; lun = lun_ch - 'a' + 1; } else { RF_ERRORMSG1("Unable to parse disk dev file name %s\n",s); return(-1); } return( (dev_major<<20) | (bus<<14) | (target<<10) | (lun<<6) | part );}/* searches a file for a line that says "START string", where string is * specified as a parameter */static int rf_search_file_for_start_of(string, buf, len, fp) char *string; char *buf; int len; FILE *fp;{ char *p; while (1) { if (fgets(buf, len, fp) == NULL) return(-1); p = rf_find_non_white(buf); if (!strncmp(p, "START", strlen("START"))) { p = rf_find_white(p); p = rf_find_non_white(p); if (!strncmp(p, string, strlen(string))) return(0); } }}/* reads from file fp into buf until it finds an interesting line */int rf_get_next_nonblank_line(buf, len, fp, errmsg) char *buf; int len; FILE *fp; char *errmsg;{ char *p; while (fgets(buf,256,fp) != NULL) { p = rf_find_non_white(buf); if (*p == '\n' || *p == '\0' || *p == '#') continue; return(0); } if (errmsg) RF_ERRORMSG(errmsg); return(1);}/* Allocates an array for the spare table, and initializes it from a file. * In the user-level version, this is called when recon is initiated. * When/if I move recon into the kernel, there'll be a daemon that does * an ioctl into raidframe which will block until a spare table is needed. * When it returns, it will read a spare table from the file system, * pass it into the kernel via a different ioctl, and then block again * on the original ioctl. * * This is specific to the declustered layout, but doesn't belong in * rf_decluster.c because it uses stuff that can't be compiled into * the kernel, and it needs to be compiled into the user-level sparemap daemon. * */void *rf_ReadSpareTable(req, fname) RF_SparetWait_t *req; char *fname;{ int i, j, numFound, linecount, tableNum, tupleNum, spareDisk, spareBlkOffset; char buf[1024], targString[100], errString[100]; RF_SpareTableEntry_t **table; FILE *fp; /* allocate and initialize the table */ RF_Malloc(table, req->TablesPerSpareRegion * sizeof(RF_SpareTableEntry_t *), (RF_SpareTableEntry_t **)); for (i=0; i<req->TablesPerSpareRegion; i++) { RF_Malloc(table[i], req->BlocksPerTable * sizeof(RF_SpareTableEntry_t), (RF_SpareTableEntry_t *)); for (j=0; j<req->BlocksPerTable; j++) table[i][j].spareDisk = table[i][j].spareBlockOffsetInSUs = -1; } /* 2. open sparemap file, sanity check */ if ((fp = fopen(fname,"r"))==NULL) { fprintf(stderr,"rf_ReadSpareTable: Can't open sparemap file %s\n",fname); return(NULL); } if (rf_get_next_nonblank_line(buf,1024,fp,"Invalid sparemap file: can't find header line\n")) return(NULL); if (buf[strlen(buf)-1] == '\n') buf[strlen(buf)-1] = '\0'; sprintf(targString, "fdisk %d\n", req->fcol); sprintf(errString, "Invalid sparemap file: can't find \"fdisk %d\" line\n",req->fcol); while (1) { rf_get_next_nonblank_line(buf,1024,fp,errString); if (!strncmp(buf,targString,strlen(targString))) break; } /* no more blank lines or comments allowed now */ linecount = req->TablesPerSpareRegion * req->TableDepthInPUs; for (i=0; i<linecount; i++) { numFound = fscanf(fp," %d %d %d %d",&tableNum, &tupleNum, &spareDisk, &spareBlkOffset); if (numFound != 4) { fprintf(stderr,"Sparemap file prematurely exhausted after %d of %d lines\n",i,linecount); return(NULL); } RF_ASSERT(tableNum >= 0 && tableNum < req->TablesPerSpareRegion); RF_ASSERT(tupleNum >= 0 && tupleNum < req->BlocksPerTable); RF_ASSERT(spareDisk >= 0 && spareDisk < req->C); RF_ASSERT(spareBlkOffset >= 0 && spareBlkOffset < req->SpareSpaceDepthPerRegionInSUs / req->SUsPerPU); table[tableNum][tupleNum].spareDisk = spareDisk; table[tableNum][tupleNum].spareBlockOffsetInSUs = spareBlkOffset * req->SUsPerPU; } fclose(fp); return((void *) table);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -