Mailinglist Archive: opensuse-de (3763 mails)

< Previous Next >
Re: warning: can't open /etc/mtab: no such file or directory
  • From: Torsten Förtsch <torsten.foertsch@xxxxxxx>
  • Date: Thu, 30 Sep 2004 23:23:44 +0200
  • Message-id: <200409302323.49261.r2@xxxxxxxx>
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On Wednesday 29 September 2004 22:12, Rolf Hoff wrote:
> hallo Torsten,
> habe inzwischen mal die initrd uncompressed und nach /mnt gemountet.
> Da habe ich unter /mnt/etc dann eine fstab gefunden, die aber einen ganz
> anderen Inhalt aufweist, als die fstab unter /etc/fstab, und zwar:
> - - - -snipp - - - -
> sysfs /sys sysfs defaults 0 0
> - - - - s n a p p - - -
> Weiter nichts.

Ich denke, Du solltest erstmal den Zweck des initrd verstehen. Also, früher
als linux noch so klein war, dass alle gängige und unterstützte Hardware in
einen ca. 1MB großen Kernel passte, brauchte man keinen initrd. Es gab
einfach zur Installation eine Boot Diskette, die den Kernel enthielt und
evtl. noch eine weitere mit einem Mini-System zur Installation. Oft enthielt
aber eine Diskette beides.

Distributoren wie Suse standen damals vor dem Problem, dass sie zur
Installation Kernel liefern mussten, die auf dem Zielsystem wenigstens
irgendwie liefen. Sonderkonfigurationen, wie z.B. ein SCSI System, musste man
oftmals später per Hand in den Kernel kompilieren. Für einen Linux Anfänger
war das keine leichte Aufgabe. Ich kann mich an Suse Versionen mit einer
ganzen Menge verschiedener Kernel erinnern, von denen man sich den aussuchte,
der am besten zur gegebenen Hardware passte.

Außerdem unterstützte Linux immer mehr Hardware, so dass es in vielen Kernels
Teile gab, die nie auf dem gegebenen System genutzt wurden, die aber immer
Hauptspeicher belegten.

Um das Problem zu lösen, wurde der Kernel modularisiert. Einzelne Treiber
können jetzt als Modul kompiliert werden und erst, wenn sie benötigt werden,
in den Kernel geladen werden. Wenn Du bei einem heutigen Suse Linux im
Betrieb mal lsmod eingibst, siehst Du wie weit dieser Prozess fortgeschritten
ist. Heute kann sogar der Keyboard- und Maustreiber als Modul kompiliert
werden.

Nun entsteht aber ein weiteres Problem. Wenn man nämlich einen stark
modularisierten Kernel hat, so ist dieser am Anfang relativ hilflos. Oft kann
er nicht mal sein Root Filesystem finden und verstehen. Dazu wurde folgende
Lösung gefunden. Der Boot Loader lädt den Kernel mit Bios-Hilfe in den
Speicher. Wenn der Boot Loader (grub oder lilo) aber den Kernel in den
Speicher laden kann, dann kann er ja auch noch ein weiteres File in den
Speicher laden. Das ist der initrd.

Nun ist der Kernel so kompiliert, dass er eine RAM Disk kennt und das ext2
Filesystem versteht. Selbst, wenn diese beiden Dinge zum eigentlichen Betrieb
nie wieder benötigt werden, müssen sie zum Booten im Kernel einkompiliert
sein. (Sie benötigen aber zum Glück recht wenig Platz). Damit kennt nun der
Kernel einen Standard-Weg, wie er ein bestimmtes Filesystem finden (mounten)
kann. Dieses mountet er als Root Filesystem.

Das Root Filesystem ist bis jetzt aber nur im Hauptspeicher und der Kernel
kennt Deine Platte immer noch nicht. Jetzt kommt ein spezielles Programm
namens "/linurc" in der initrd zum Zuge. Der Kernel startet einfach dieses
Programm und geht davon aus, dass es den Kernel schon irgendwie so
konfiguriert, dass er danach das eigentliche Root Filesystem (auf der Platte)
findet.

Meist muss linuxrc dafür nicht viel mehr machen, als z.B. den SCSI / IDE
Treiber und den Treiber für reiserfs zu laden. Er kann aber auch ein
Netzwerk-Interface konfigurieren und das Root Filesystem über nfs mounten.

Damit linuxrc (meist ein Shell Script) seine Arbeit tun kann muss der initrd
die nötigen Teile mitbringen. Da wären (mindestens):

- - wenigstens eine Shell samt nötiger shared libs
- - insmod
- - die benötigten Module

Als letztes schreibt initrd die Device Nummer des eigentlichen Root
Filesystems nach /proc/sys/kernel/real-root-dev. Dafür muss aber das proc
Filesystem auch gemountet sein. Und hier kommt Dein mount Problem. Linuxrc
versucht irgendwann /proc zu mounten und der mount Befehl gibt die Warnung
aus. Normalerweise kann man mit der Option -n verhindern, dass mount oder
umount /etc/mtab versuchen zu schreiben. Suse hat wohl an einer Stelle
in /linuxrc vergessen, diese Option mitzugeben:

opi:/home # cat /mnt/linuxrc | grep mount
mount -n -tproc proc /proc
mount -n -tsysfs sysfs /sys > /dev/null 2>&1
mount -n -ttmpfs tmpfs /dev/shm
umount -n /proc
umount -n /sys
umount /dev/shm <== das ist der Schuldige

> Mit welchem Inhalt muss denn dann die /etc/mtab nach /mnt/etc/mtab
> (in die initrd hinein) kopiert bzw. geschrieben werden?

So, nun denke ich dargelegt zu haben, dass Du gar kein /etc/mtab in Deinem
initrd brauchst. Du müsstest einfach den Fehler in linuxrc beheben. Dieser
wird allerdings mit /sbin/mkinitrd erzeugt. Dort habe ich bei mir folgendes
gefunden:

opi:/home # cat -n /sbin/mkinitrd |grep -C5 1337
1332 |done
1333 |
1334 |die() {
1335 | umount -n /proc
1336 | umount -n /sys
1337 | umount /dev/shm <== the culprit
1338 | exit \$1
1339 |}
1340 |
1341 |# Fallback root device number
1342 |rootdevn=$rootdevn

In Zeile 1337 fehlt einfach das -n.

> Außerdem habe ich auch festgestellt, dass es unter /mnt/proc/
> keine /mnt/proc/mounts (in der initrd) gibt.

natürlich. Wenn Dein System normal läuft, ist das proc Filesystem ja als /proc
gemountet. Wenn der initrd in Betrieb ist, also in einer der ersten Phasen
des Bootens, ist er als Root Filesystem (/) gemountet. Linuxrc mountet dann
proc nach /proc (im initrd) und umountet /proc am Ende wieder.

> Wenn es nun keine /proc/mounts in der initrd gibt, warum sollte
> dann /etc/mtab etwas in der initrd zu suchen haben?

siehe oben

> Noch bei der Gelegenheit:
> Bei einem "mkinitrd" nach Thomas Hertweck wie folgt:
> - - -  s n i p p - - -
> mkinitrd -k /boot/vmlinuz -i /boot/initrd-2.6.5-7.108-1 -s 1024x768
> - - - - s n a p p - - -
> gibt es anschließend keine *.gz, und trotzdem ist die Datei
> komprimiert.

Linux/Unix gibt nicht sehr viel auf Endungen wie .gz. In der urspünglichen
Philosophie steht der Typ eines Files oder des Inhalts irgendwie
maschinenlesbar am Anfang des Files. Meist nennt man diesen Marker "magic
number". Ganz durchhalten lies sich das nicht. Aber ein nützliches Kommando,
wenn Du nicht weißt, was ein File ist, ist "file". Es benutzt den Inhalt des
Files:

opi:/home #
file /boot/initrd /boot/initrd-2.6.8-20040918095208-default /tmp/initrd.uncompressed /mnt/linuxrc /bin/bash
/boot/initrd: symbolic link to
`initrd-2.6.8-20040918095208-default'
/boot/initrd-2.6.8-20040918095208-default: gzip compressed data, was
"initrd_small", from Unix, max compression
/tmp/initrd.uncompressed: Linux rev 1.0 ext2 filesystem data
(mounted or unclean)
/mnt/linuxrc: Bourne shell script text
/bin/bash: ELF 32-bit LSB executable, Intel
80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically
linked (uses shared libs), stripped


> Würde mich freuen, wenn Du diese Fragen auch noch beantworten
> würdest. Jetzt interessiert mich das alles nun auch noch.
> Wirklich.

Hat's geholfen?

Torsten
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (GNU/Linux)

iD8DBQFBXHllwicyCTir8T4RAmjGAJ9rjVjFYu0UqSOFgH5av0PknINlHgCffgAX
fqX69m0gR7hrpCmmr/WczqM=
=nWki
-----END PGP SIGNATURE-----

< Previous Next >