Module Name: src Committed By: martin Date: Mon Sep 10 17:56:00 UTC 2018
Modified Files: src/sbin/raidctl [netbsd-8]: raidctl.8 rf_configure.c rf_configure.h Log Message: Pull up following revision(s) (requested by nakayama in ticket #1019): sbin/raidctl/rf_configure.h: revision 1.2 sbin/raidctl/rf_configure.c: revision 1.27 sbin/raidctl/rf_configure.c: revision 1.28 sbin/raidctl/rf_configure.c: revision 1.29 sbin/raidctl/raidctl.8: revision 1.73 sbin/raidctl/rf_configure.c: revision 1.30 sbin/raidctl/rf_configure.c: revision 1.31 sbin/raidctl/rf_configure.c: revision 1.32 support NAME=<wedge name> syntax for disks and spares - stop using magic constants wrap long lines use warn{,x} make static knf - White space and comment formatting. NFC. - With char bug[SIZE] using sizeof(bug[0]) is kind of boring, use sizeof(bug) instead... - Avoid needless pointer calisthenics: &foo[0] -> foo - Several more cleanups: 1. Don't force use of "for" when "while" works better. 2. No need to check c != '\0' when we also check (c == ' ' || c == '\t') 3. Use the size of the buffer we're using, rather than a different one (not really a concern, they're the same size) 4. Don't use fscanf() to read file data, use fgets() & sscanf(). 5. After using a pointer as a char *, validate alignment before switching to int * (can only fail if kernel #define gets set stupidly) Or #6... 6. Validate sparemap file name isn't too long for assigned space. 7. recognise that strlen() returns size_t - don't shove it into an int. 8. On out of mem, be more clear which allocation failed in warning msg. ATF tests all pass. But I don't think they use sparemap files. To generate a diff of this commit: cvs rdiff -u -r1.71 -r1.71.8.1 src/sbin/raidctl/raidctl.8 cvs rdiff -u -r1.26 -r1.26.8.1 src/sbin/raidctl/rf_configure.c cvs rdiff -u -r1.1 -r1.1.92.1 src/sbin/raidctl/rf_configure.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sbin/raidctl/raidctl.8 diff -u src/sbin/raidctl/raidctl.8:1.71 src/sbin/raidctl/raidctl.8:1.71.8.1 --- src/sbin/raidctl/raidctl.8:1.71 Wed Jan 6 22:57:44 2016 +++ src/sbin/raidctl/raidctl.8 Mon Sep 10 17:56:00 2018 @@ -1,4 +1,4 @@ -.\" $NetBSD: raidctl.8,v 1.71 2016/01/06 22:57:44 wiz Exp $ +.\" $NetBSD: raidctl.8,v 1.71.8.1 2018/09/10 17:56:00 martin Exp $ .\" .\" Copyright (c) 1998, 2002 The NetBSD Foundation, Inc. .\" All rights reserved. @@ -388,6 +388,7 @@ START disks .Ed .Pp specifies the three component disks to be used in the RAID device. +Disk wedges may also be specified with the NAME=<wedge name> syntax. If any of the specified drives cannot be found when the RAID device is configured, then they will be marked as .Sq failed , Index: src/sbin/raidctl/rf_configure.c diff -u src/sbin/raidctl/rf_configure.c:1.26 src/sbin/raidctl/rf_configure.c:1.26.8.1 --- src/sbin/raidctl/rf_configure.c:1.26 Wed Mar 9 19:53:32 2016 +++ src/sbin/raidctl/rf_configure.c Mon Sep 10 17:56:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: rf_configure.c,v 1.26 2016/03/09 19:53:32 christos Exp $ */ +/* $NetBSD: rf_configure.c,v 1.26.8.1 2018/09/10 17:56:00 martin Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. @@ -49,7 +49,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: rf_configure.c,v 1.26 2016/03/09 19:53:32 christos Exp $"); +__RCSID("$NetBSD: rf_configure.c,v 1.26.8.1 2018/09/10 17:56:00 martin Exp $"); #endif @@ -58,6 +58,7 @@ __RCSID("$NetBSD: rf_configure.c,v 1.26 #include <errno.h> #include <strings.h> #include <err.h> +#include <util.h> #include <sys/types.h> #include <sys/stat.h> @@ -65,22 +66,23 @@ __RCSID("$NetBSD: rf_configure.c,v 1.26 #include <dev/raidframe/raidframeio.h> #include "rf_configure.h" -RF_LayoutSW_t *rf_GetLayout(RF_ParityConfig_t parityConfig); -char *rf_find_non_white(char *p); -char *rf_find_white(char *p); +static char *rf_find_non_white(char *, int); +static char *rf_find_white(char *); +static int rf_search_file_for_start_of(const char *, char *, int, FILE *); +static int rf_get_next_nonblank_line(char *, int, FILE *, const char *); + #define RF_MIN(a,b) (((a) < (b)) ? (a) : (b)) -#define RF_ERRORMSG(s) printf((s)) -#define RF_ERRORMSG1(s,a) printf((s),(a)) -#define RF_ERRORMSG2(s,a,b) printf((s),(a),(b)) - -int distSpareYes = 1; -int distSpareNo = 0; - -/* The mapsw[] table below contains all the various RAID types that might -be supported by the kernel. The actual supported types are found -in sys/dev/raidframe/rf_layout.c. */ -static RF_LayoutSW_t mapsw[] = { +static int distSpareYes = 1; +static int distSpareNo = 0; + +/* + * The mapsw[] table below contains all the various RAID types that might + * be supported by the kernel. The actual supported types are found + * in sys/dev/raidframe/rf_layout.c. + */ + +static const RF_LayoutSW_t mapsw[] = { /* parity declustering */ {'T', "Parity declustering", rf_MakeLayoutSpecificDeclustered, &distSpareNo}, @@ -114,61 +116,61 @@ static RF_LayoutSW_t mapsw[] = { /* end-of-list marker */ {'\0', NULL, NULL, NULL} }; -RF_LayoutSW_t * + +static const RF_LayoutSW_t * rf_GetLayout(RF_ParityConfig_t parityConfig) { - RF_LayoutSW_t *p; + const RF_LayoutSW_t *p; /* look up the specific layout */ for (p = &mapsw[0]; p->parityConfig; p++) if (p->parityConfig == parityConfig) break; if (!p->parityConfig) - return (NULL); - return (p); + return NULL; + return p; } -static int rf_search_file_for_start_of(const char *string, char *buf, - int len, FILE * fp); -static int rf_get_next_nonblank_line(char *buf, int len, FILE * fp, - const char *errmsg); - /* * called from user level to read the configuration file and create * a configuration control structure. This is used in the user-level * version of the driver, and in the user-level program that configures * the system via ioctl. */ -int +int rf_MakeConfig(char *configname, RF_Config_t *cfgPtr) { int numscanned, val, r, c, retcode, aa, bb, cc; - char buf[256], buf1[256], *cp; - RF_LayoutSW_t *lp; + char buf[BUFSIZ], buf1[BUFSIZ], *cp; + const RF_LayoutSW_t *lp; FILE *fp; - bzero((char *) cfgPtr, sizeof(RF_Config_t)); + memset(cfgPtr, 0, sizeof(*cfgPtr)); fp = fopen(configname, "r"); if (!fp) { - printf("Can't open config file %s\n", configname); - return (-1); + warnx("Can't open config file %s", configname); + return -1; } rewind(fp); - if (rf_search_file_for_start_of("array", buf, 256, fp)) { - printf("Unable to find start of \"array\" params in config file %s\n", configname); + if (rf_search_file_for_start_of("array", buf, sizeof(buf), fp)) { + warnx("Unable to find start of \"array\" params in config " + "file %s", configname); retcode = -1; goto out; } - rf_get_next_nonblank_line(buf, 256, fp, "Config file error (\"array\" section): unable to get numRow and numCol\n"); + rf_get_next_nonblank_line(buf, sizeof(buf), fp, + "Config file error (\"array\" section): unable to get numRow " + "and numCol"); /* - * wackiness with aa, bb, cc to get around size problems on - * different platforms - */ + * wackiness with aa, bb, cc to get around size problems on + * different platforms + */ numscanned = sscanf(buf, "%d %d %d", &aa, &bb, &cc); if (numscanned != 3) { - printf("Config file error (\"array\" section): unable to get numRow, numCol, numSpare\n"); + warnx("Config file error (\"array\" section): unable to get " + "numRow, numCol, numSpare"); retcode = -1; goto out; } @@ -180,38 +182,42 @@ rf_MakeConfig(char *configname, RF_Confi for (c = 0; c < RF_MAXDBGV; c++) cfgPtr->debugVars[c][0] = '\0'; rewind(fp); - if (!rf_search_file_for_start_of("debug", buf, 256, fp)) { + if (!rf_search_file_for_start_of("debug", buf, sizeof(buf), fp)) { for (c = 0; c < RF_MAXDBGV; c++) { - if (rf_get_next_nonblank_line(buf, 256, fp, NULL)) + if (rf_get_next_nonblank_line(buf, sizeof(buf), fp, + NULL)) break; - cp = rf_find_non_white(buf); - if (!strncmp(cp, "START", strlen("START"))) + cp = rf_find_non_white(buf, 0); + if (!strncmp(cp, "START", sizeof("START") - 1)) break; - (void) strlcpy(&cfgPtr->debugVars[c][0], cp, + (void) strlcpy(cfgPtr->debugVars[c], cp, sizeof(cfgPtr->debugVars[c])); } } rewind(fp); strlcpy(cfgPtr->diskQueueType, "fifo", sizeof(cfgPtr->diskQueueType)); cfgPtr->maxOutstandingDiskReqs = 1; + /* scan the file for the block related to disk queues */ - if (rf_search_file_for_start_of("queue", buf, 256, fp)) { - RF_ERRORMSG2("[No disk queue discipline specified in config file %s. Using %s.]\n", configname, cfgPtr->diskQueueType); - } else { - if (rf_get_next_nonblank_line(buf, 256, fp, NULL)) { - RF_ERRORMSG2("[No disk queue discipline specified in config file %s. Using %s.]\n", configname, cfgPtr->diskQueueType); - } + if (rf_search_file_for_start_of("queue", buf, sizeof(buf), fp) || + rf_get_next_nonblank_line(buf, sizeof(buf), fp, NULL)) { + warnx("[No disk queue discipline specified in config file %s. " + "Using %s.]", configname, cfgPtr->diskQueueType); } - /* the queue specifier line contains two entries: 1st char of first + /* + * the queue specifier line contains two entries: 1st char of first * word specifies queue to be used 2nd word specifies max num reqs - * that can be outstanding on the disk itself (typically 1) */ - if (sscanf(buf, "%255s %d", buf1, &val) != 2) { - RF_ERRORMSG1("Can't determine queue type and/or max outstanding reqs from line: %s", buf); - RF_ERRORMSG2("Using %s-%d\n", cfgPtr->diskQueueType, cfgPtr->maxOutstandingDiskReqs); + * that can be outstanding on the disk itself (typically 1) + */ + if (sscanf(buf, "%s %d", buf1, &val) != 2) { + warnx("Can't determine queue type and/or max outstanding " + "reqs from line: %*s", (int)(sizeof(buf) - 1), buf); + warnx("Using %s-%d", cfgPtr->diskQueueType, + cfgPtr->maxOutstandingDiskReqs); } else { char *ch; - bcopy(buf1, cfgPtr->diskQueueType, + memcpy(cfgPtr->diskQueueType, buf1, RF_MIN(sizeof(cfgPtr->diskQueueType), strlen(buf1) + 1)); for (ch = buf1; *ch; ch++) { if (*ch == ' ') { @@ -224,44 +230,75 @@ rf_MakeConfig(char *configname, RF_Confi rewind(fp); - if (rf_search_file_for_start_of("disks", buf, 256, fp)) { - RF_ERRORMSG1("Can't find \"disks\" section in config file %s\n", configname); + if (rf_search_file_for_start_of("disks", buf, sizeof(buf), fp)) { + warnx("Can't find \"disks\" section in config file %s", + configname); retcode = -1; goto out; } for (r = 0; r < cfgPtr->numRow; r++) { for (c = 0; c < cfgPtr->numCol; c++) { + char b1[MAXPATHLEN]; + const char *b; + if (rf_get_next_nonblank_line( - &cfgPtr->devnames[r][c][0], 50, fp, NULL)) { - RF_ERRORMSG2("Config file error: unable to get device file for disk at row %d col %d\n", r, c); + buf, sizeof(buf), fp, NULL)) { + warnx("Config file error: unable to get device " + "file for disk at row %d col %d", r, c); retcode = -1; goto out; } + + b = getfsspecname(b1, sizeof(b1), buf); + if (b == NULL) { + warnx("Config file error: warning: unable to " + "get device file for disk at row %d col " + "%d: %s", r, c, b1); + b = buf; + } + + strlcpy(cfgPtr->devnames[r][c], b, + sizeof(cfgPtr->devnames[r][c])); } } /* "spare" section is optional */ rewind(fp); - if (rf_search_file_for_start_of("spare", buf, 256, fp)) + if (rf_search_file_for_start_of("spare", buf, sizeof(buf), fp)) cfgPtr->numSpare = 0; for (c = 0; c < cfgPtr->numSpare; c++) { - if (rf_get_next_nonblank_line(&cfgPtr->spare_names[c][0], - 256, fp, NULL)) { - RF_ERRORMSG1("Config file error: unable to get device file for spare disk %d\n", c); + char b1[MAXPATHLEN]; + const char *b; + + if (rf_get_next_nonblank_line(buf, sizeof(buf), fp, NULL)) { + warnx("Config file error: unable to get device file " + "for spare disk %d", c); retcode = -1; goto out; } + + b = getfsspecname(b1, sizeof(b1), buf); + if (b == NULL) { + warnx("Config file error: warning: unable to get " + "device file for spare disk %d: %s", c, b); + b = buf; + } + + strlcpy(cfgPtr->spare_names[r], b, + sizeof(cfgPtr->spare_names[r])); } /* scan the file for the block related to layout */ rewind(fp); - if (rf_search_file_for_start_of("layout", buf, 256, fp)) { - RF_ERRORMSG1("Can't find \"layout\" section in configuration file %s\n", configname); + if (rf_search_file_for_start_of("layout", buf, sizeof(buf), fp)) { + warnx("Can't find \"layout\" section in configuration file %s", + configname); retcode = -1; goto out; } - if (rf_get_next_nonblank_line(buf, 256, fp, NULL)) { - RF_ERRORMSG("Config file error (\"layout\" section): unable to find common layout param line\n"); + if (rf_get_next_nonblank_line(buf, sizeof(buf), fp, NULL)) { + warnx("Config file error (\"layout\" section): unable to find " + "common layout param line"); retcode = -1; goto out; } @@ -270,89 +307,94 @@ rf_MakeConfig(char *configname, RF_Confi cfgPtr->SUsPerPU = (RF_StripeNum_t) bb; cfgPtr->SUsPerRU = (RF_StripeNum_t) cc; if (c != 4) { - RF_ERRORMSG("Unable to scan common layout line\n"); + warnx("Unable to scan common layout line"); retcode = -1; goto out; } lp = rf_GetLayout(cfgPtr->parityConfig); if (lp == NULL) { - RF_ERRORMSG1("Unknown parity config '%c'\n", + warnx("Unknown parity config '%c'", cfgPtr->parityConfig); retcode = -1; goto out; } - retcode = lp->MakeLayoutSpecific(fp, cfgPtr, lp->makeLayoutSpecificArg); + retcode = lp->MakeLayoutSpecific(fp, cfgPtr, + lp->makeLayoutSpecificArg); out: fclose(fp); if (retcode < 0) retcode = errno = EINVAL; else errno = retcode; - return (retcode); + return retcode; } -/* used in architectures such as RAID0 where there is no layout-specific +/* + * used in architectures such as RAID0 where there is no layout-specific * information to be passed into the configuration code. */ -int +int rf_MakeLayoutSpecificNULL(FILE *fp, RF_Config_t *cfgPtr, void *ignored) { cfgPtr->layoutSpecificSize = 0; cfgPtr->layoutSpecific = NULL; - return (0); + return 0; } -int +int rf_MakeLayoutSpecificDeclustered(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]; + char buf[BUFSIZ], smbuf[BUFSIZ]; 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'; - } + if (rf_get_next_nonblank_line(buf, sizeof(buf), configfp, + "Can't find block design file name in config file")) + return EINVAL; + bdfile = rf_find_non_white(buf, 1); /* 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); - } - if (fgets(buf, 256, fp) == NULL) { - RF_ERRORMSG1("RAID: config error: Can't read layout from layout table file %s\n", bdfile); + warn("RAID: config error: Can't open layout table file %s", + bdfile); + return EINVAL; + } + if (fgets(buf, sizeof(buf), fp) == NULL) { + warnx("RAID: config error: Can't read layout from layout " + "table file %s", bdfile); fclose(fp); - return (EINVAL); + return EINVAL; } - i = sscanf(buf, "%u %u %u %u %u %u", &b, &v, &k, &r, &lambda, &norotate); + 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"); + warnx("Unable to parse header line in block design file"); fclose(fp); - return (EINVAL); + return EINVAL; } - /* set the sparemap directory. In the in-kernel version, there's a - * daemon that's responsible for finding the sparemaps */ + /* + * 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")) { + if (rf_get_next_nonblank_line(smbuf, sizeof(smbuf), configfp, + "Can't find sparemap file name in config file")) { fclose(fp); - return (EINVAL); + return EINVAL; } - smname = rf_find_non_white(smbuf); - if (smname[strlen(smname) - 1] == '\n') { - /* strip newline char */ - smname[strlen(smname) - 1] = '\0'; + smname = rf_find_non_white(smbuf, 1); + if (strlen(smname) >= RF_SPAREMAP_NAME_LEN) { + warnx("sparemap file name '%s' too long (max %d)", + smname, RF_SPAREMAP_NAME_LEN - 1); + fclose(fp); + return EINVAL; } } else { smbuf[0] = '\0'; @@ -366,7 +408,7 @@ rf_MakeLayoutSpecificDeclustered(FILE *c cfgBuf = (char *) malloc(cfgPtr->layoutSpecificSize); if (cfgBuf == NULL) { fclose(fp); - return (ENOMEM); + return ENOMEM; } cfgPtr->layoutSpecific = (void *) cfgBuf; p = cfgBuf; @@ -379,11 +421,18 @@ rf_MakeLayoutSpecificDeclustered(FILE *c *p++ = '\0'; i++; } + if ((i & (sizeof(int) - 1)) != 0) { + /* panic, unaligned data; RF_SPAREMAP_NAME_LEN invalid */ + warnx("Program Bug: (RF_SPAREMAP_NAME_LEN(%d) %% %zd) != 0", + RF_SPAREMAP_NAME_LEN, sizeof(int)); + fclose(fp); + return EINVAL; + } /* - * fill in the buffer with the block design parameters - * and then the block design itself - */ + * fill in the buffer with the block design parameters + * and then the block design itself + */ *((int *) p) = b; p += sizeof(int); *((int *) p) = v; @@ -401,10 +450,11 @@ rf_MakeLayoutSpecificDeclustered(FILE *c *p++ = (char) val; fclose(fp); if ((unsigned int)(p - cfgBuf) != cfgPtr->layoutSpecificSize) { - RF_ERRORMSG2("Size mismatch creating layout specific data: is %d sb %d bytes\n", (int) (p - cfgBuf), (int) (6 * sizeof(int) + b * k)); - return (EINVAL); + warnx("Size mismatch creating layout specific data: is %tu sb " + "%zu bytes", p - cfgBuf, 6 * sizeof(int) + b * k); + return EINVAL; } - return (0); + return 0; } /**************************************************************************** @@ -414,64 +464,66 @@ rf_MakeLayoutSpecificDeclustered(FILE *c ***************************************************************************/ /* finds a non-white character in the line */ -char * -rf_find_non_white(char *p) +static char * +rf_find_non_white(char *p, int eatnl) { - for (; *p != '\0' && (*p == ' ' || *p == '\t'); p++); - return (p); + while (*p == ' ' || *p == '\t') + p++; + if (*p == '\n' && eatnl) + *p = '\0'; + return p; } /* finds a white character in the line */ -char * +static char * rf_find_white(char *p) { - for (; *p != '\0' && (*p != ' ' && *p != '\t'); p++); - return (p); + while (*p != '\0' && *p != ' ' && *p != '\t') + p++; + return p; } /* * searches a file for a line that says "START string", where string is * specified as a parameter */ -static int +static int rf_search_file_for_start_of(const 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); + return -1; + p = rf_find_non_white(buf, 0); if (!strncmp(p, "START", strlen("START"))) { p = rf_find_white(p); - p = rf_find_non_white(p); + p = rf_find_non_white(p, 0); if (!strncmp(p, string, strlen(string))) - return (0); + return 0; } } } /* reads from file fp into buf until it finds an interesting line */ -int +static int rf_get_next_nonblank_line(char *buf, int len, FILE *fp, const char *errmsg) { char *p; - int l; + size_t l; while (fgets(buf, len, fp) != NULL) { - p = rf_find_non_white(buf); + p = rf_find_non_white(buf, 0); if (*p == '\n' || *p == '\0' || *p == '#') continue; - l = strlen(buf)-1; - while (l>=0 && (buf[l]==' ' || buf[l]=='\n')) { - buf[l]='\0'; - l--; - } - return (0); + l = strlen(buf); + while (l > 0 && (buf[--l] == ' ' || buf[l] == '\n')) + buf[l] = '\0'; + return 0; } if (errmsg) - RF_ERRORMSG1("%s", errmsg); - return (1); + warnx("%s", errmsg); + return 1; } /* @@ -486,16 +538,16 @@ rf_get_next_nonblank_line(char *buf, int * 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(RF_SparetWait_t *req, char *fname) { int i, j, numFound, linecount, tableNum, tupleNum, spareDisk, spareBlkOffset; - char buf[1024], targString[100], errString[100]; + char buf[BUFSIZ], targString[BUFSIZ], errString[BUFSIZ]; RF_SpareTableEntry_t **table; FILE *fp = NULL; + size_t len; /* allocate and initialize the table */ table = calloc(req->TablesPerSpareRegion, sizeof(*table)); @@ -506,7 +558,7 @@ rf_ReadSpareTable(RF_SparetWait_t *req, for (i = 0; i < req->TablesPerSpareRegion; i++) { table[i] = calloc(req->BlocksPerTable, sizeof(**table)); if (table[i] == NULL) { - warn("%s: Unable to allocate table", __func__); + warn("%s: Unable to allocate table:%d", __func__, i); goto out; } for (j = 0; j < req->BlocksPerTable; j++) @@ -520,19 +572,18 @@ rf_ReadSpareTable(RF_SparetWait_t *req, goto out; } if (rf_get_next_nonblank_line(buf, 1024, fp, - "Invalid sparemap file: can't find header line\n")) + "Invalid sparemap file: can't find header line")) goto out; - size_t len = strlen(buf); + len = strlen(buf); if (len != 0 && buf[len - 1] == '\n') buf[len - 1] = '\0'; snprintf(targString, sizeof(targString), "fdisk %d\n", req->fcol); snprintf(errString, sizeof(errString), - "Invalid sparemap file: can't find \"fdisk %d\" line\n", - req->fcol); + "Invalid sparemap file: Can't find \"fdisk %d\" line", req->fcol); for (;;) { - rf_get_next_nonblank_line(buf, 1024, fp, errString); + rf_get_next_nonblank_line(buf, sizeof(buf), fp, errString); if (!strncmp(buf, targString, strlen(targString))) break; } @@ -540,13 +591,21 @@ rf_ReadSpareTable(RF_SparetWait_t *req, /* 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) { + char linebuf[BUFSIZ]; + + if (fgets(linebuf, BUFSIZ, fp) == NULL) { warnx("Sparemap file prematurely exhausted after %d " "of %d lines", i, linecount); goto out; } + numFound = sscanf(linebuf, " %d %d %d %d", &tableNum, &tupleNum, + &spareDisk, &spareBlkOffset); + if (numFound != 4) { + warnx("Sparemap file format error - " + "line %d of %d lines", + i + 1, linecount); + goto out; + } table[tableNum][tupleNum].spareDisk = spareDisk; table[tableNum][tupleNum].spareBlockOffsetInSUs = @@ -554,7 +613,7 @@ rf_ReadSpareTable(RF_SparetWait_t *req, } fclose(fp); - return ((void *) table); + return (void *) table; out: if (fp) fclose(fp); Index: src/sbin/raidctl/rf_configure.h diff -u src/sbin/raidctl/rf_configure.h:1.1 src/sbin/raidctl/rf_configure.h:1.1.92.1 --- src/sbin/raidctl/rf_configure.h:1.1 Thu Oct 4 16:00:37 2001 +++ src/sbin/raidctl/rf_configure.h Mon Sep 10 17:56:00 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: rf_configure.h,v 1.1 2001/10/04 16:00:37 oster Exp $ */ +/* $NetBSD: rf_configure.h,v 1.1.92.1 2018/09/10 17:56:00 martin Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. * All rights reserved. @@ -45,9 +45,9 @@ #include <sys/proc.h> #include <sys/ioctl.h> -int rf_MakeConfig(char *configname, RF_Config_t * cfgPtr); -int rf_MakeLayoutSpecificNULL(FILE * fp, RF_Config_t * cfgPtr, void *arg); -int rf_MakeLayoutSpecificDeclustered(FILE * configfp, RF_Config_t * cfgPtr, void *arg); -void *rf_ReadSpareTable(RF_SparetWait_t * req, char *fname); +int rf_MakeConfig(char *, RF_Config_t *); +int rf_MakeLayoutSpecificNULL(FILE *, RF_Config_t *, void *); +int rf_MakeLayoutSpecificDeclustered(FILE *, RF_Config_t *, void *); +void *rf_ReadSpareTable(RF_SparetWait_t *, char *); -#endif /* !_RF__RF_CONFIGURE_H_ */ +#endif /* !_RF__RF_CONFIGURE_H_ */