97 lines
1.8 KiB
C
97 lines
1.8 KiB
C
/*
|
|
* Having the wrong rootdevice listed in mtab is slightly inconvenient.
|
|
* Try to guess what it could be...
|
|
* In case /proc/cmdline exists, and has the format
|
|
* stuff root=R more stuff...
|
|
* and we think we understand the number R, decode it as a root device.
|
|
*
|
|
* Another possibility:
|
|
* Erik Andersen writes:
|
|
* I did a similar find_real_root_device_name() in busybox some time back.
|
|
* Basically, do a stat("/", &rootstat) then walk /dev stat'ing each file
|
|
* and if (statbuf.st_rdev == rootstat.st_rdev) then you have a match.
|
|
* Works fine.
|
|
*/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include "mount_guess_rootdev.h"
|
|
|
|
#define PROC_CMDLINE "/proc/cmdline"
|
|
|
|
static char *
|
|
rootdev(char *p) {
|
|
unsigned long devno;
|
|
char *ep;
|
|
char *type = "hd";
|
|
char let;
|
|
int ma, mi;
|
|
char devname[32];
|
|
|
|
devno = strtoul(p, &ep, 16);
|
|
if ((ep == p+3 || ep == p+4) && (*ep == ' ' || *ep == 0)) {
|
|
ma = (devno >> 8);
|
|
mi = (devno & 0xff);
|
|
switch(ma) {
|
|
case 8:
|
|
type = "sd";
|
|
let = 'a'+(mi/16);
|
|
mi = mi%16;
|
|
break;
|
|
case 3:
|
|
let = 'a'; break;
|
|
case 0x16:
|
|
let = 'c'; break;
|
|
case 0x21:
|
|
let = 'e'; break;
|
|
case 0x22:
|
|
let = 'g'; break;
|
|
case 0x38:
|
|
let = 'i'; break;
|
|
case 0x39:
|
|
let = 'k'; break;
|
|
default:
|
|
return NULL;
|
|
}
|
|
if (mi & 0x40) {
|
|
mi -= 0x40;
|
|
let++;
|
|
}
|
|
if (mi == 0)
|
|
sprintf(devname, "/dev/%s%c", type, let);
|
|
else
|
|
sprintf(devname, "/dev/%s%c%d", type, let, mi);
|
|
return xstrdup(devname);
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
char *
|
|
mount_guess_rootdev() {
|
|
FILE *cf;
|
|
char line[1024];
|
|
char *p, *ret = NULL;
|
|
|
|
cf = fopen(PROC_CMDLINE, "r");
|
|
if (cf) {
|
|
if (fgets(line, sizeof(line), cf)) {
|
|
for (p = line; *p; p++) {
|
|
if (!strncmp(p, " root=", 6)) {
|
|
ret = rootdev(p+6);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
fclose(cf);
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
#if 0
|
|
main(){
|
|
char *p = mount_guess_rootdev();
|
|
if (!p)
|
|
p = "/dev/root";
|
|
printf("%s\n", p);
|
|
}
|
|
#endif
|