1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <sys/types.h>
#include <sys/sysmacros.h>
#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;
dir = opendir(sysdir);
if (!dir)
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");
sysdev = fopen(sysdir, "r");
if (!sysdev)
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 */
|