]> git.ipfire.org Git - thirdparty/util-linux.git/blob - mount/mount_guess_rootdev.c
Imported from util-linux-2.10s tarball.
[thirdparty/util-linux.git] / mount / mount_guess_rootdev.c
1 /*
2 * Having the wrong rootdevice listed in mtab is slightly inconvenient.
3 * Try to guess what it could be...
4 * In case /proc/cmdline exists, and has the format
5 * stuff root=R more stuff...
6 * and we think we understand the number R, decode it as a root device.
7 *
8 * Another possibility:
9 * Erik Andersen writes:
10 * I did a similar find_real_root_device_name() in busybox some time back.
11 * Basically, do a stat("/", &rootstat) then walk /dev stat'ing each file
12 * and if (statbuf.st_rdev == rootstat.st_rdev) then you have a match.
13 * Works fine.
14 */
15 #include <stdio.h>
16 #include <string.h>
17 #include "mount_guess_rootdev.h"
18
19 #define PROC_CMDLINE "/proc/cmdline"
20
21 static char *
22 rootdev(char *p) {
23 unsigned long devno;
24 char *ep;
25 char *type = "hd";
26 char let;
27 int ma, mi;
28 char devname[8];
29
30 devno = strtoul(p, &ep, 16);
31 if ((ep == p+3 || ep == p+4) && (*ep == ' ' || *ep == 0)) {
32 ma = (devno >> 8);
33 mi = (devno & 0xff);
34 switch(ma) {
35 case 8:
36 type = "sd";
37 let = 'a'+(mi/16);
38 mi = mi%16;
39 break;
40 case 3:
41 let = 'a'; break;
42 case 0x16:
43 let = 'c'; break;
44 case 0x21:
45 let = 'e'; break;
46 case 0x22:
47 let = 'g'; break;
48 case 0x38:
49 let = 'i'; break;
50 case 0x39:
51 let = 'k'; break;
52 default:
53 return NULL;
54 }
55 if (mi & 0x40) {
56 mi -= 0x40;
57 let++;
58 }
59 if (mi == 0)
60 sprintf(devname, "/dev/%s%c", type, let);
61 else
62 sprintf(devname, "/dev/%s%c%d", type, let, mi);
63 return strdup(devname);
64 }
65 return NULL;
66 }
67
68 char *
69 mount_guess_rootdev() {
70 FILE *cf;
71 char line[1024];
72 char *p;
73
74 cf = fopen(PROC_CMDLINE, "r");
75 if (cf && fgets(line, sizeof(line), cf)) {
76 for (p = line; *p; p++)
77 if (!strncmp(p, " root=", 6))
78 return rootdev(p+6);
79 }
80 return NULL;
81 }
82
83 #if 0
84 main(){
85 char *p = mount_guess_rootdev();
86 if (!p)
87 p = "/dev/root";
88 printf("%s\n", p);
89 }
90 #endif