The init script checkroot uses a touch test to determine whether /etc/mtab is writable. If touch fails, it skips /etc/mtab initialization. However, when /etc/mtab is a symlink to /proc/mounts as is common on ro root systems, touch returns successfully, even though /etc is not writable. The easiest fix seems to be to use some other file in /etc which is less likely to be a symlink for the touch test, e.g. /etc/fstab. Reproducible: Always Steps to Reproduce:
Created attachment 144207 [details, diff] Patch to place mtab in /var/lib/misc Maybe it would be best to move mtab to /var - after all, it's hardly static configuration. That would mean a one-line patch to glibc (attached) and mounting /var before the mtab initialization code if necessary (working on that).
please post `emerge --info` as documented in the Bug Reporting guide i cannot see /etc/mtab being used anywhere as a test for read only root we are not going to change glibc in any way wrt mtab
Portage 2.1.4.4 (default-linux/x86/2007.0/desktop, gcc-4.1.2, glibc-2.6.1-r0, 2.6.23-gentoo-r8 i686) ================================================================= System uname: 2.6.23-gentoo-r8 i686 Pentium III (Coppermine) Timestamp of tree: Wed, 20 Feb 2008 22:30:01 +0000 app-shells/bash: 3.2_p17-r1 dev-java/java-config: 1.3.7, 2.0.33-r1 dev-lang/python: 2.4.4-r6 dev-python/pycrypto: 2.0.1-r6 sys-apps/baselayout: 1.12.11.1 sys-apps/sandbox: 1.2.18.1-r2 sys-devel/autoconf: 2.13, 2.61-r1 sys-devel/automake: 1.5, 1.7.9-r1, 1.8.5-r3, 1.9.6-r2, 1.10 sys-devel/binutils: 2.18-r1 sys-devel/gcc-config: 1.4.0-r4 sys-devel/libtool: 1.5.26 virtual/os-headers: 2.6.23-r3 ACCEPT_KEYWORDS="x86" CBUILD="i686-pc-linux-gnu" CFLAGS="-march=pentium3 -mfpmath=sse -mmmx -msse -O2 -pipe" CHOST="i686-pc-linux-gnu" CONFIG_PROTECT="/etc" CONFIG_PROTECT_MASK="/etc/env.d /etc/env.d/java/ /etc/fonts/fonts.conf /etc/gconf /etc/php/apache2-php5/ext-active/ /etc/php/cgi-php5/ext-active/ /etc/php/cli-php5/ext-active/ /etc/revdep-rebuild /etc/splash /etc/terminfo /etc/udev/rules.d" CXXFLAGS="-march=pentium3 -mfpmath=sse -mmmx -msse -O2 -pipe" DISTDIR="/usr/portage/distfiles" FEATURES="distlocks metadata-transfer sandbox sfperms strict unmerge-orphans userfetch" GENTOO_MIRRORS="http://distfiles.gentoo.org http://distro.ibiblio.org/pub/linux/distributions/gentoo" LANG="C" LINGUAS="en_GB de" PKGDIR="/usr/portage/packages" PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress --force --whole-file --delete --stats --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages" PORTAGE_TMPDIR="/var/tmp" PORTDIR="/usr/portage" SYNC="rsync://rsync.gentoo.org/gentoo-portage" USE="X aac acl acpi alsa avahi berkdb bitmap-fonts bzip2 cairo cddb cdr cli cracklib crypt cups dbus dri dvd dvdr dvdread eds emboss encode esd evo fam firefox fortran gdbm gif gnome gpm gstreamer gtk hal iconv imap ipv6 isdnlog java jpeg kerberos ldap lua mad midi mikmod mmx mng mp3 mpeg mudflap ncurses nls nptl nptlonly ogg opengl openmp oss pam pcre pdf perl php png pppd python qt3support quicktime readline reflection samba sdl session spell spl sse ssl svg syslog tcpd tiff truetype truetype-fonts type1-fonts unicode vorbis win32codecs x86 xinerama xml xorg xv xvmc zlib" ALSA_CARDS="ali5451 als4000 atiixp atiixp-modem bt87x ca0106 cmipci emu10k1 emu10k1x ens1370 ens1371 es1938 es1968 fm801 hda-intel intel8x0 intel8x0m maestro3 trident usb-audio via82xx via82xx-modem ymfpci" ALSA_PCM_PLUGINS="adpcm alaw asym copy dmix dshare dsnoop empty extplug file hooks iec958 ioplug ladspa lfloat linear meter mulaw multi null plug rate route share shm softvol" APACHE2_MODULES="actions alias auth_basic authn_alias authn_anon authn_dbm authn_default authn_file authz_dbm authz_default authz_groupfile authz_host authz_owner authz_user autoindex cache dav dav_fs dav_lock deflate dir disk_cache env expires ext_filter file_cache filter headers include info log_config logio mem_cache mime mime_magic negotiation rewrite setenvif speling status unique_id userdir usertrack vhost_alias" ELIBC="glibc" INPUT_DEVICES="keyboard mouse" KERNEL="linux" LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses text" LINGUAS="en_GB de" USERLAND="GNU" VIDEO_CARDS="nvidia" Unset: CPPFLAGS, CTARGET, EMERGE_DEFAULT_OPTS, INSTALL_MASK, LC_ALL, LDFLAGS, MAKEOPTS, PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS, PORTDIR_OVERLAY
The test is in /etc/init.d/checkroot line 99: # Don't create mtab if /etc is readonly if ! touch /etc/mtab 2> /dev/null ; then ewarn "Skipping /etc/mtab initialization (ro root?)" return 0 fi What about a patch to include use flag support for mtab under /var, would that be accepted?
that test does not matter at all. if /etc/mtab is a symlink to /proc/mounts, then there is nothing for the function to do, as /etc/mtab does not need updating. the only change that could be made is to not warn if /etc/mtab is not writable, but i dont think it really matters that much. i'm not adding anything to glibc for mtab control. create a symlink from /etc/mtab to /var/.... if you want to put it in /var.
*** Bug 214182 has been marked as a duplicate of this bug. ***
Created attachment 146809 [details, diff] handle /etc/mtab to ../proc/mounts symlink tiny patch to sys-apps/baselayout`s /etc/init.d/checkroot to handle /etc/mtab symlink to /proc/mounts correctly.
please reopen..
we're not going to hardcode a list of all the possible mtab symlinks the warning is just that -- a warning. it isnt an error that prevents your system from booting properly.
The warning is supposed to be displayed if /etc is readonly, and processing aborted, because after this the script goes on to initialise /etc/mtab. However, if that is a symlink, the script does NOT warn, and it does NOT stop processing - it thinks it's writable, as touch returns successfully, and happily tries to setup /etc/mtab, which of course fails. I don't really remember whether this leads to the boot "failing" or whether it just spams ugly error messages, but since checkroot is normally critical, I'd guess it fails. Either way, error messages were not acceptable as these systems will be "monitored" by non-experts who won't be able to tell which errors are errors and which ones are not (and errors that are not should never be displayed in the first place, really). I've since changed my RO base system to keep mtab under /var/lib/misc by using the glibc patch above and making some changes to checkroot and localmount. If anyone is interested in what I did, I'd be happy to provide a patch for that also. P.S.: simply creating a link /etc/mtab -> /var/lib/misc/mtab won't cut it, as of course your rw filesystem must be mounted first, and any other mounts in the path to /var/lib/misc/mtab!
P.P.S.: the easiest fix - without touching glibc or changing anything about the order in which things happen at boot - is the one stated in the original bug submission: just touch some other file in /etc which is unlikely to be a symlink instead.
have you guys actually read the init.d script ? there is no bug here. you're told: Skipping /etc/mtab initialization and if your /etc/mtab is a symlink to /proc/mounts, that is *exactly* what happens. the very last thing that happens in checkroot is /etc/mtab updating. if it cant be updated for whatever reason, you get a message that it is being skipped. so what ? as for "just check another file", what exactly would be the point ? the code is doing exactly *1 thing*: updating /etc/mtab. it is *not* to see if / is read only. in fact, it could care less. all it cares about is that /etc/mtab was not updated.
(In reply to comment #13) > have you guys actually read the init.d script ? there is no bug here. you're > told: > Skipping /etc/mtab initialization > > and if your /etc/mtab is a symlink to /proc/mounts, that is *exactly* what > happens. the very last thing that happens in checkroot is /etc/mtab updating. > if it cant be updated for whatever reason, you get a message that it is being > skipped. so what ? yes, i read the checkroot init script and your assumption that the "touch /etc/mtab"-check (skipping /etc/mtab initializing) works in this case is wrong. so the awk '$2 != "/" {print}' /proc/mounts >> /etc/mtab results in an error message (because /etc/mtab is not writeable) which does not hurt but is ugly and can be easily avoided by the symlink check i added.
Since I actually pasted code from the script above, indicating exactly where it goes wrong, the question whether I read it is a bit silly, don't you think? The script relies on the assumption that touch will return a NON-ZERO return code if /etc/mtab is not writable - however, if it is a symlink it will return a ZERO return code, aka "successful". The code which I pasted above therefore does NOT enter the if block, it does NOT print the ewarn and it does NOT return. Instead, it tries to write to a symlink to /proc/mounts, which obviously fails. I really don't know how much more clearly I can possibly put this. Testing a different file in /etc (like /etc/fstab) would circumvent the problem with touch returning zero when touching a symlink pointing to /proc, as the file in question would NOT be a symlink. That way, you'd know /etc is not writable and could skip the mtab init.
as spanky wrote, its no good idea to hardcode all possible symlinks. so a better solution maybe is to check if /etc/mtab just is a symlink (not where it points to), because if it is a symlink we do not want to (try to) overwrite it anyway. so changing if [[ ${BOOT} == "yes" ]] ; then to if [[ ${BOOT} == "yes" ]] && [[ ! `readlink /etc/mtab` ]] ; then should be enough daniel, please reopen.