grub-devel
[Top][All Lists]
Advanced

[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

Attachment: stat_vs_statfs.c
Description: Text Data


reply via email to

[Prev in Thread] Current Thread [Next in Thread]