diff options
author | Radek Vykydal <rvykydal@redhat.com> | 2008-09-12 16:03:27 +0200 |
---|---|---|
committer | Radek Vykydal <rvykydal@redhat.com> | 2008-09-12 16:03:27 +0200 |
commit | e6c2919597a14eeda943bb7db7c73e1ba75216a0 (patch) | |
tree | ea5730b3a8801620c4cc81bf3faebf351713a7ff /isys | |
parent | 482cc178808de67dcc721e81b0f9a11512e434dc (diff) | |
download | anaconda-e6c2919597a14eeda943bb7db7c73e1ba75216a0.tar.gz anaconda-e6c2919597a14eeda943bb7db7c73e1ba75216a0.tar.xz anaconda-e6c2919597a14eeda943bb7db7c73e1ba75216a0.zip |
Fix device nodes creating for more than 8 cciss devices (#445765).
Major numbers for more than 8 controllers are assigned dynamically,
read them from /proc/devices. For up to 32 devices (which is the
number current driver supports) cache is used.
Diffstat (limited to 'isys')
-rw-r--r-- | isys/devnodes.c | 71 |
1 files changed, 64 insertions, 7 deletions
diff --git a/isys/devnodes.c b/isys/devnodes.c index 963319f39..0ef2301de 100644 --- a/isys/devnodes.c +++ b/isys/devnodes.c @@ -87,12 +87,56 @@ static int sd_major(int major_idx) { } } -/* virtio has a dynamically assigned major; poke around - * in /proc/devices for it. +struct devmajor { + char *name; + short major; +}; + +static struct devmajor dynamic_major_cache[] = { + { "virtblk", -1 }, + { "cciss8", -1 }, + { "cciss9", -1 }, + { "cciss10", -1 }, + { "cciss11", -1 }, + { "cciss12", -1 }, + { "cciss13", -1 }, + { "cciss14", -1 }, + { "cciss15", -1 }, + { "cciss16", -1 }, + { "cciss17", -1 }, + { "cciss18", -1 }, + { "cciss19", -1 }, + { "cciss20", -1 }, + { "cciss21", -1 }, + { "cciss22", -1 }, + { "cciss23", -1 }, + { "cciss24", -1 }, + { "cciss25", -1 }, + { "cciss26", -1 }, + { "cciss27", -1 }, + { "cciss28", -1 }, + { "cciss29", -1 }, + { "cciss30", -1 }, + { "cciss31", -1 }, +}; + +int majCacheSize = sizeof(dynamic_major_cache) / sizeof(struct devmajor); + +/* + * find dynamically assigned major in /proc/devices */ -static int virtio_major(void) { +static int dynamic_major(char *devname) { FILE *f; - static int retval = -1; + int retval = -1; + int cacheIdx; + + /* look into cache */ + for (cacheIdx = 0; cacheIdx < majCacheSize; cacheIdx++) { + if (!strcmp(dynamic_major_cache[cacheIdx].name, devname)) { + retval = dynamic_major_cache[cacheIdx].major; + break; + } + } if (retval != -1) return retval; @@ -121,10 +165,13 @@ static int virtio_major(void) { while (*p == ' ') p++; - if (strncmp(p, "virtblk", sizeof("virtblk") - 1) != 0) + if (strncmp(p, devname, strlen(devname)) != 0) continue; retval = major; + if (cacheIdx != majCacheSize) + dynamic_major_cache[cacheIdx].major = major; + break; } @@ -275,7 +322,7 @@ int devMakeInode(char * devName, char * path) { } } else if (devName[0] == 'v' && devName[1] == 'd') { type = S_IFBLK; - major = virtio_major(); + major = dynamic_major("virtblk"); if (major < 0) return major; minor = virtio_minor(devName); @@ -363,7 +410,17 @@ int devMakeInode(char * devName, char * path) { c = d = p = 0; e = sscanf(devName + 6, "c%dd%dp%d", &c, &d, &p); type = S_IFBLK; - major = 104 + c; /* controller */ + if (c < 8) { + /* reserved major numbers */ + major = 104 + c; /* controller */ + } else { + /* dynamically assigned major numbers */ + char cname[11]; + snprintf(cname, 10, "cciss%d", c); + major = dynamic_major(cname); + if (major < 0) + return major; + } minor = d * 16; /* disk */ minor += p; /* partition */ } else if (!strncmp(devName, "ataraid/", 8)) { |