#include #include #include #include #include #include #include #include "kinit.h" /* * Print the name of a block device. */ #define BUF_SIZE 512 static int scansysdir(char *namebuf, char *sysdir, dev_t dev) { char *dirtailptr = strchr(sysdir, '\0'); DIR *dir; int done = 0; struct dirent *de; char *systail; FILE *sysdev; unsigned long ma, mi; char *ep; ssize_t rd; if (!(dir = opendir(sysdir))) return 0; *dirtailptr++ = '/'; while (!done && (de = readdir(dir))) { /* Assume if we see a dot-name in sysfs it's special */ if (de->d_name[0] == '.') continue; if (de->d_type != DT_UNKNOWN && de->d_type != DT_DIR) continue; if (strlen(de->d_name) >= (BUF_SIZE - 64) - (dirtailptr - sysdir)) continue; /* Badness... */ strcpy(dirtailptr, de->d_name); systail = strchr(sysdir, '\0'); strcpy(systail, "/dev"); if (!(sysdev = fopen(sysdir, "r"))) continue; /* Abusing the namebuf as temporary storage here. */ rd = fread(namebuf, 1, BUF_SIZE, sysdev); namebuf[rd] = '\0'; /* Just in case... */ fclose(sysdev); ma = strtoul(namebuf, &ep, 10); if (ma != major(dev) || *ep != ':') continue; mi = strtoul(ep + 1, &ep, 10); if (*ep != '\n') continue; if (mi == minor(dev)) { /* Found it! */ strcpy(namebuf, de->d_name); done = 1; } else { /* we have a major number match, scan for partitions */ *systail = '\0'; done = scansysdir(namebuf, sysdir, dev); } } closedir(dir); return done; } const char *bdevname(dev_t dev) { static char buf[BUF_SIZE]; char sysdir[BUF_SIZE]; char *p; strcpy(sysdir, "/sys/block"); if (!scansysdir(buf, sysdir, dev)) strcpy(buf, "dev"); /* prints e.g. dev(3,5) */ p = strchr(buf, '\0'); snprintf(p, sizeof buf - (p - buf), "(%d,%d)", major(dev), minor(dev)); return buf; } #ifdef TEST_DEVNAME /* Standalone test */ int main(int argc, char *argv[]) { dev_t dev; int i; for (i = 1; i < argc; i++) { dev = strtoul(argv[i], NULL, 0); printf("0x%08x = %s\n", (unsigned int)dev, bdevname(dev)); } return 0; } #endif /* TEST */