X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=util.c;h=2cb6dd316f8e173ab913e54a778e96110a450524;hb=e81cdd9f3794d2b4452ae2297c43e16e3faf6f6a;hp=873deba67eacdb434e7a5c272d1182ddebc5f3ef;hpb=16c6fa807c1e43a1a12bbeb7668b4166d14b2cc8;p=thirdparty%2Fmdadm.git diff --git a/util.c b/util.c index 873deba6..2cb6dd31 100644 --- a/util.c +++ b/util.c @@ -1,7 +1,7 @@ /* * mdadm - manage Linux "md" devices aka RAID arrays. * - * Copyright (C) 2001-2002 Neil Brown + * Copyright (C) 2001-2006 Neil Brown * * * This program is free software; you can redistribute it and/or modify @@ -357,6 +357,7 @@ int devlist_ready = 0; #ifdef UCLIBC int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s) { + return 0; } char *map_dev(int major, int minor, int create) { @@ -375,26 +376,32 @@ int add_dev_1(const char *name, const struct stat *stb, int flag) } int nftw(const char *path, int (*han)(const char *name, const struct stat *stb, int flag, struct FTW *s), int nopenfd, int flags) { - ftw(path, add_dev_1, nopenfd); + return ftw(path, add_dev_1, nopenfd); } #endif int add_dev(const char *name, const struct stat *stb, int flag, struct FTW *s) { - if ((stb->st_mode&S_IFMT)== S_IFBLK) { - char *n = strdup(name); - struct devmap *dm = malloc(sizeof(*dm)); - if (strncmp(n, "/dev/.", 6)==0) - strcpy(n+4, name+6); - if (dm) { - dm->major = major(stb->st_rdev); - dm->minor = minor(stb->st_rdev); - dm->name = n; - dm->next = devlist; - devlist = dm; + struct stat st; + if (S_ISLNK(stb->st_mode)) { + stat(name, &st); + stb = &st; } - } - return 0; + + if ((stb->st_mode&S_IFMT)== S_IFBLK) { + char *n = strdup(name); + struct devmap *dm = malloc(sizeof(*dm)); + if (strncmp(n, "/dev/./", 7)==0) + strcpy(n+4, name+6); + if (dm) { + dm->major = major(stb->st_rdev); + dm->minor = minor(stb->st_rdev); + dm->name = n; + dm->next = devlist; + devlist = dm; + } + } + return 0; } /* @@ -408,14 +415,27 @@ char *map_dev(int major, int minor, int create) { struct devmap *p; char *std = NULL, *nonstd=NULL; + int did_check = 0; + + if (major == 0 && minor == 0) + return NULL; + + retry: if (!devlist_ready) { char *dev = "/dev"; struct stat stb; + while(devlist) { + struct devmap *d = devlist; + devlist = d->next; + free(d->name); + free(d); + } if (lstat(dev, &stb)==0 && S_ISLNK(stb.st_mode)) dev = "/dev/."; nftw(dev, add_dev, 10, FTW_PHYS); devlist_ready=1; + did_check = 1; } for (p=devlist; p; p=p->next) @@ -431,9 +451,13 @@ char *map_dev(int major, int minor, int create) nonstd = p->name; } } + if (!std && !nonstd && !did_check) { + devlist_ready = 0; + goto retry; + } if (create && !std && !nonstd) { static char buf[30]; - snprintf(buf, 1024, "%d:%d", major, minor); + snprintf(buf, sizeof(buf), "%d:%d", major, minor); nonstd = buf; } @@ -609,8 +633,12 @@ int dev_open(char *dev, int flags) char *e; int fd = -1; char devname[32]; - int major = strtoul(dev, &e, 0); + int major; int minor; + + if (!dev) return -1; + + major = strtoul(dev, &e, 0); if (e > dev && *e == ':' && e[1] && (minor = strtoul(e+1, &e, 0)) >= 0 && *e == 0) {