--- lsraid.c 2004-02-25 10:53:06.000000000 -0500 +++ lsraid.c 2004-02-26 15:24:25.000000000 -0500 @@ -56,10 +56,6 @@ #define LSRAID_VERSION "0.7.0" /* Imagine the fun when we get to different major,minor sizes :-) */ -#define MAJORBITS 8 -#define MINORBITS 8 -#define MAJORS (1 << MAJORBITS) -#define MINORS (1 << MINORBITS) /* Debugging for device scanning */ #define SCAN_DEBUG 0 @@ -73,6 +69,7 @@ typedef struct _LSRDir LSRDir; typedef struct _LSRArray LSRArray; typedef struct _LSRDisk LSRDisk; +typedef struct _LSRDevtable LSRDevtable; @@ -95,6 +92,13 @@ LSR_DEV_SCAN = 1 << 4 } LSRFlags; +struct _LSRDevtable +{ + int major; + int minor; + char* name; + LSRDevtable* next, *prev; +}; /* @@ -108,8 +112,7 @@ struct list_head o_disks; /* Disk names from parse_options */ struct list_head arrays; /* Anchor for list of arrays (a_list) */ struct list_head disks; /* Anchor for list of disks (d_list) */ - char ***devtable; /* Table of known device names - (major, minor) -> name */ + LSRDevtable* devtable; }; struct _LSRNamEnt @@ -159,6 +162,8 @@ /* * Prototypes */ +static char* getname(LSRContext* ctxt, int major, int minor); +static int add_devtable(LSRContext* ctxt, int major, int minor, char* name); static void print_usage(int rc); static void print_usage_long(); static void print_version(); @@ -213,7 +218,54 @@ /* * Functions */ +static char* getname(LSRContext* ctxt, int major, int minor) +{ + LSRDevtable* head=ctxt->devtable; + ctxt->devtable=ctxt->devtable->next; + while(ctxt->devtable->name!="") + { + if(ctxt->devtable->minor==minor) + if(ctxt->devtable->major==major) + break; + ctxt->devtable=ctxt->devtable->next; + } + if(ctxt->devtable->name!="") + { + LSRDevtable* temp = ctxt->devtable; + ctxt->devtable=head; + return temp->name; + } + else + { + return NULL; + } +} +static int add_devtable(LSRContext* ctxt, int major, int minor, char* name) +{ + int rc=0; + if(ctxt->devtable) + { + LSRDevtable* temp = (LSRDevtable*)malloc(sizeof(LSRDevtable)); + if (!temp) + { + rc = -ENOMEM; + } + else + { + temp->major=major; + temp->minor=minor; + temp->name=name; + ctxt->devtable->prev->next=temp; + temp->prev=ctxt->devtable->prev; + temp->next=ctxt->devtable; + ctxt->devtable->prev=temp; + } + } + else + rc = -ENOMEM; + return(rc); +} static void print_version() { @@ -258,13 +310,17 @@ INIT_LIST_HEAD(&ctxt->o_arrays); INIT_LIST_HEAD(&ctxt->disks); INIT_LIST_HEAD(&ctxt->arrays); - ctxt->devtable = (char ***)malloc(MAJORS * sizeof(char **)); + ctxt->devtable = (LSRDevtable*)malloc(sizeof(LSRDevtable)); if (!ctxt->devtable) { free(ctxt); return(NULL); } - memset(ctxt->devtable, 0, MAJORS * sizeof(char **)); + ctxt->devtable->major=0; + ctxt->devtable->minor=0; + ctxt->devtable->name=""; + ctxt->devtable->next=ctxt->devtable; + ctxt->devtable->prev=ctxt->devtable; } return(ctxt); } /* alloc_context() */ @@ -973,14 +1029,14 @@ { fprintf(stderr, "lsraid: Unable to allocate memory for information on device \"%s\": %s\n", - ctxt->devtable[major][minor], + getname(ctxt,major,minor), strerror(errno)); return; } } proc_name[0] = '\0'; - dev_base = strrchr(ctxt->devtable[major][minor], '/'); + dev_base = strrchr(getname(ctxt,major,minor), '/'); if ((dev_base == NULL) || (dev_base[1] == '\0')) return; @@ -1013,11 +1069,11 @@ { fprintf(stderr, "lsraid: Unable to allocate memory for information on device \"%s\": %s\n", - ctxt->devtable[major][minor], + getname(ctxt,major,minor), strerror(errno)); return; } - ent->name = ctxt->devtable[major][minor]; + ent->name = getname(ctxt,major,minor); /* Should we add MD_MAJOR devices to o_disks too? */ if (major == MD_MAJOR) @@ -1058,45 +1114,26 @@ if (*name && major) { - if (!ctxt->devtable[major]) - { - ctxt->devtable[major] = - (char **)malloc(MINORS * sizeof(char *)); - if (!ctxt->devtable[major]) - { - rc = -ENOMEM; - break; - } - memset(ctxt->devtable[major], 0, - MINORS * sizeof(char *)); - } - - if (ctxt->devtable[major][minor]) + if(getname(ctxt,major,minor)) continue; - /* - * This is all '/dev' specific. If it isn't found there, - * it is going to fall back to /dev scanning (think - * /dev/usb/disk1 or something in devfs). This heuristic - * should probably check whatever devfs puts together - * for 'hda1 in /proc/partitions', but I don't know what - * devfs does, and I don't much care right now. - */ - ctxt->devtable[major][minor] = - (char *)malloc((strlen(name) + strlen("/dev/") + 1) * - sizeof(char)); - if (!ctxt->devtable[major][minor]) + char* tempstr = (char *)malloc((strlen(name) + strlen("/dev/") + 1) * + sizeof(char)); + if(!tempstr) continue; - sprintf(ctxt->devtable[major][minor], "/dev/%s", name); - - rc = stat(ctxt->devtable[major][minor], &stat_buf); - if ((rc != 0) && (!S_ISBLK(stat_buf.st_mode))) - { - free(ctxt->devtable[major][minor]); - ctxt->devtable[major][minor] = NULL; - } - else if (ctxt->flags & LSR_DEV_SCAN) - maybe_add_device(ctxt, major, minor); + sprintf(tempstr, "/dev/%s", name); + + rc = stat(tempstr, &stat_buf); + if ((rc != 0) && (!S_ISBLK(stat_buf.st_mode))) + { + free(tempstr); + tempstr= NULL; + } + else if (ctxt->flags & LSR_DEV_SCAN) + { + if(add_devtable(ctxt,major,minor,tempstr)==0) + maybe_add_device(ctxt, major, minor); + } } } @@ -1241,26 +1278,15 @@ { major = major(stat_buf.st_rdev); minor = minor(stat_buf.st_rdev); - if (!ctxt->devtable[major]) + if(getname(ctxt,major,minor)) + continue; + + char* tempstr = (char *)malloc((strlen(name) + 1) * sizeof(char)); + if(tempstr) { - ctxt->devtable[major] = - (char **)malloc(MINORS * sizeof(char *)); - if (!ctxt->devtable[major]) - { - /* FIXME: what error if any? rc = -ENOMEM; */ - continue; - } - memset(ctxt->devtable[major], 0, - MINORS * sizeof(char *)); + strcpy(tempstr, name); + add_devtable(ctxt,major,minor,tempstr); } - - if (ctxt->devtable[major][minor]) - continue; - - ctxt->devtable[major][minor] = - (char *)malloc((strlen(name) + 1) * sizeof(char)); - if (ctxt->devtable[major][minor]) - strcpy(ctxt->devtable[major][minor], name); } } @@ -1298,14 +1324,14 @@ if (!major) return(-EINVAL); - if (ctxt->devtable[major] && ctxt->devtable[major][minor]) + if(getname(ctxt,major,minor)) goto out; if (!loaded_partitions) { load_partitions(ctxt); loaded_partitions = 1; - if (ctxt->devtable[major] && ctxt->devtable[major][minor]) + if(getname(ctxt,major,minor)) goto out; } @@ -1313,15 +1339,15 @@ { scan_slash_dev(ctxt); scanned_dev = 1; - if (ctxt->devtable[major] && ctxt->devtable[major][minor]) + if(getname(ctxt,major,minor)) goto out; } rc = -ENOENT; out: - if (ctxt->devtable[major]) - *name = ctxt->devtable[major][minor]; + if(getname(ctxt,major,minor)) + *name=getname(ctxt,major,minor); return(rc); } /* find_device() */ @@ -1398,7 +1424,6 @@ static void clean_context(LSRContext *ctxt) { - int i; struct list_head *pos, *n; LSRArray *array; LSRDisk *disk; @@ -1426,10 +1451,13 @@ } if (ctxt->devtable) { - for (i = 0; i < MAJORS; i++) - if (ctxt->devtable[i]) - free(ctxt->devtable[i]); - free(ctxt->devtable); + LSRDevtable* head=ctxt->devtable; + do + { + LSRDevtable* temp=ctxt->devtable; + ctxt->devtable=ctxt->devtable->next; + free(temp); + }while(ctxt->devtable != head); } free(ctxt); } /* clean_context() */ @@ -2613,6 +2641,7 @@ * Main program */ +#ifndef TESTING /*for FNST testing*/ int main(int argc, char *argv[]) { int i; @@ -2653,3 +2682,4 @@ clean_context(ctxt); return(0); } /* main() */ +#endif /*TESTING*/