[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
grub-probe && statfs(2)
From: |
Francis Gendreau |
Subject: |
grub-probe && statfs(2) |
Date: |
Sat, 29 Dec 2007 07:36:46 -0500 |
Hello everyone,
I'd like to know if someone here conceived using the statfs() system
call in find_root_device() (or grub_guess_root_device()) instead of
doing a linear look-up into the /dev directory.
My concern here is, that on FreeBSD system using devfs or not, the
approach employed by find_root_device() of getting the dev_t from struct
stat st_dev is not functional. The reason is simple, the function assume
that the st_dev value would be identical for an inode of a particular
device and for the device entry of /dev.
I wrote a short program (in attachment), that provided me the proof of
what I am reporting below.
FreeBSD-4.11 > ./test $HOME /dev/ad0s1f /tmp /dev/ad0s1h / /dev/ad0s1a
$HOME : dev_t=160773, mntfrom="/dev/ad0s1f", mnton="/home"
/dev/ad0s1f : dev_t=160768, mntfrom="/dev/ad0s1a", mnton="/"
/tmp : dev_t=160775, mntfrom="/dev/ad0s1h", mnton="/tmp"
/dev/ad0s1h : dev_t=160768, mntfrom="/dev/ad0s1a", mnton="/"
/ : dev_t=160768, mntfrom="/dev/ad0s1a", mnton="/"
/dev/ad0s1a : dev_t=160768, mntfrom="/dev/ad0s1a", mnton="/"
Freebsd-6.2_devfs> ./test . /dev/ad4s1h /tmp /dev/ad4s1e / /dev/ad4s1a /dev /mnt
. : dev_t=117, mntfrom="/dev/ad4s1h", mnton="/home"
/dev/ad4s1h : dev_t=16842496, mntfrom="devfs", mnton="/dev"
/tmp : dev_t=114, mntfrom="/dev/ad4s1e", mnton="/tmp"
/dev/ad4s1e : dev_t=16842496, mntfrom="devfs", mnton="/dev"
/ : dev_t=110, mntfrom="/dev/ad4s1a", mnton="/"
/dev/ad4s1a : dev_t=16842496, mntfrom="devfs", mnton="/dev"
/dev : dev_t=16842496, mntfrom="devfs", mnton="/dev"
/mnt : dev_t=138, mntfrom="/dev/ad0s1a", mnton="/mnt"
OpenBSD-3.2 > ./test . /dev/wd0a /mnt/cdrom/I386 /dev/cd0a
. : dev_t=0, mntfrom="/dev/wd0a", mnton="/"
/dev/wd0a : dev_t=0, mntfrom="/dev/wd0a", mnton="/"
/mnt/cdrom/I386 : dev_t=768, mntfrom="/dev/cd0a", mnton="/mnt/cdrom"
/dev/cd0a : dev_t=0, mntfrom="/dev/wd0a", mnton="/"
Speculating, it seems there is a difference between 44BSD (?) and Linux
in the assigned value of st_dev. While Linux seems to set the same value
for the inodes on the device and the device entry in /dev, BSDs tends to
treat entries in /dev as inodes of the device there are stored on.
My recommendation would be relatively simple. grub_guess_root_device()
could simply call statfs() and extract the device name from struct
statfs f_mntfromname, maybe as simply as the following, but I may lack
of knowledge about some technologies on which this might not work (like
RAID ...).
size_t strnlen (const char *s, size_t max)
{
size_t l = 0;
if ( s )
for (; l < max && *s ; ++l );
return l;
}
char *
grub_guess_root_device (const char *path)
{
char *ret = NULL;
struct statfs sfsb;
if ( statfs (path, &sfsb) )
{
ret = xmalloc (strnlen (sfsb.f_mntfromname, MNAMELEN));
if ( ret )
strncpy (ret, sfsb.f_mntfromname, MNAMELEN);
else
{
perror ("Root device string allocation failed!");
exit (ENOMEM);
}
}
else
{
grub_util_error ("unable to stat `%s'", path);
}
return ret;
}
I would like to know what you guys think about this.
Francis Gendreau
stat_vs_statfs.c
Description: Text Data
- grub-probe && statfs(2),
Francis Gendreau <=