Bug 175243 - /proc/mounts references /dev/root for / but /dev/root does not exist
|
Bug#:
175243
|
Product: Gentoo Linux
|
Version: 2006.1
|
Platform: All
|
|
OS/Version: Linux
|
Status: RESOLVED
|
Severity: normal
|
Priority: P2
|
|
Resolution: FIXED
|
Assigned To: udev-bugs@gentoo.org
|
Reported By: cardoe@gentoo.org
|
|
Component: Ebuilds
|
|
|
URL:
|
|
Summary: /proc/mounts references /dev/root for / but /dev/root does not exist
|
|
Keywords:
|
|
Status Whiteboard:
|
|
Opened: 2007-04-19 16:27 0000
|
Basically if you look at /proc/mounts on a system booted with or without our
initramfs, you will see that in /proc/mounts that the kernel says /dev/root is
mounted as the / device. However there is no /dev/root device.
Straight from the mount(8) man page...
When the proc filesystem is mounted (say at /proc), the files /etc/mtab
and /proc/mounts have very similar contents. The former has somewhat
more information, such as the mount options used, but is not necessar-
ily up-to-date (cf. the -n option below). It is possible to replace
/etc/mtab by a symbolic link to /proc/mounts, and especially when you
have very large numbers of mounts things will be much faster with that
symlink, but some information is lost that way, and in particular work-
ing with the loop device will be less convenient, and using the "user"
option will fail.
my suggestions are:
A: In hal init-script (or before: like end of udev-start): read major/minor of
dir "/" and mknod /dev/root if it does not exist
B: let code search inside /dev for the device with that major/minor and link to
it.
getting major/minor cannot use program stat (at least not in udev) as stat is
in /usr.
We need a small helper call syscall stat and extract the info from there.
C: Adding a udev rule similar to this:
SUBSYSTEM=="block", PROGRAM=="check_if_i_am_root", SYMLINK="root"
and that program (check_if_i_am_root) compares major/minor of the device to
that of "/" directory.
something like:
major=getenv("MAJOR");
minor=getenv("MINOR");
dev_t dev=stat("/");
if (major/minor == dev)
return EXIT_SUCCESS;
else
return EXIT_FAILURE;
D: Patching hal to do this:
if (device=="/dev/root") {
device=lookup_real_name;
}
I feel that hal shouldn't be relying on the devices listed in /proc/mounts
existing. As /proc/mounts is kernel-space but filesystem contents are
controlled in userspace (and operations are not really filtered by the kernel),
there's no way consistency can be guaranteed.
Some examples for when these devices nodes might not exist:
1. When the kernel mounts the root filesystem during boot. There is no
userspace here and no /dev. The kernel has to choose a name for the node, or
not list it at all. There is no guarantee that userspace will create the same
name later.
2. When a mounted usb flash drive is unplugged, the device goes away but the
mount does not.
3. The user could remove a mounted node, or /dev might be replaced by another
layout entirely (this happens during initramfs pivot, for example).
4. Many things in /proc/mounts don't correspond to device nodes anyway, e.g.
sysfs
The kernel documentation does not comment on the accuracy of the device nodes
listed in /proc/mounts. Neither does the mount documentation. FWIW, I also
think a kernel documentation patch would be accepted to add some comments
pointing out the obvious that device nodes referred to in /proc/mounts may not
actually exist in userspace (because what userspace does in this sense is not
kernel business). Maybe this would change your views on the solution here.
IMO hal should do something different. Even though creating /dev/root would
workaround the majority of problems, I don't feel that it is a solution, and
given our crazy user-base you'll probably get that one guy who files an obscure
bug later for a different device node.
I'm just curious why genkernel is on here. We don't use udev (anymore) at all
in our initramfs stuff, as we've replaced it with mdev from busybox to reduce
size and complexity. Of course, I might just be missing something important.
;]
Because the initramfs needs to create the proper node as well.. whatever that's
getting populated as. SuSE and RedHat's initramfs is doing the right thing and
mounting the device for the kernel so it's a non-issue. But I don't know if
your initramfs does this...
My system doesn't show /dev/root in /proc/mount (because in my case it's
mounted by initramfs, not the kernel itself), so the warning is bogus on my
machine.
An even better way to get the root device, rather than getting it from
/proc/cmdline (which may not work, since if you use LILO the root device
gets
turned into a number), is to do
mount -fv / | cut -d' ' -f1
or equivalently,
mount -fv / | awk { print $1 ; }
thanks for your comments.
i added this to /etc/conf.d/local.start
ROOT_DEVICE=`mount -fv / | cut -d' ' -f1`
ln -s ${ROOT_DEVICE} /dev/root
do i need to create the device before hal is started, or is this a good method
?
I personally feel this is a kernel bug. Since we're instructing the kernel via
root= what dev device it should use. It should respect that, after all it does
for initramfs so why not for root=.
Attached is a patch to do such with the kernel.
Created an attachment (id=116919) [details]
use root= rather then hardcoding to /dev/root
The other advantage of this is that we don't have to search and compare every
block device. It's also not a userspace hack to fix a kernel space bug.
I was just wondering... What's the exact goal of this /dev/root thing? Because
if I'm using an initrd, my kernel command line option will be root=/dev/ram0,
if I'm not, it will be /dev/sda6. I don't see the use for a /dev/root that is
based on the way I boot, but I guess I'm missing something...
For me the warning is bogus too right now, there's no /dev/root in my
/proc/mounts, the only references are:
rootfs / rootfs rw 0 0
/dev/sda6 / reiserfs rw,noatime 0 0
Please enlighten me...
Michael,
When you use an initramfs (initrd), the kernel does the right thing. As you can
see there, your device for / is /dev/sda6.
This bug is for when there is no initramfs.
Since this bug is for behavior that occurs when there is *not* an initramfs,
I'm removing genkernel.
This is fixed. udev handles it fine now so /dev/root will exist.