Here is the situation. I put the hard-disk of my laptop in my desktop and performed a long-overdue update. However, all files in /etc on my laptop were overwritten. I was able to reproduce the problem with "emerge baselayout". Reproducible: Always Steps to Reproduce: 1. export ROOT=/remote/mouse 2. vim /remote/mouse/etc/fstab 3. fix something in the file. save and exit. 4. emerge baselayout Actual Results: /remote/mouse/etc/fstab was overwritten with the emerged version from the package Expected Results: /remote/mouse/etc/fstab should have been left alone and the new should have gone in /remote/mouse/etc/._cfg0000_fstab Portage 2.0.50-r7 (default-x86-2004.0, gcc-3.3.3, glibc-2.3.3_pre20040207-r0, 2.6.6-x2) ================================================================= System uname: 2.6.6-x2 i686 AMD Athlon(TM) XP 1800+ Gentoo Base System version 1.4.15 distcc 2.14 i686-pc-linux-gnu (protocols 1 and 2) (default port 3632) [disabled] ccache version 2.3 [enabled] Autoconf: sys-devel/autoconf-2.59-r3 Automake: sys-devel/automake-1.8.3 ACCEPT_KEYWORDS="x86" ACCEPT_LICENSE="" ANT_HOME="/usr/share/ant" ARCH="x86" AUTOCLEAN="yes" AUTO_SYMLINK="yes" BASH_ENV="/etc/portage/bashrc" CC="gcc" CFLAGS="-march=pentium-mmx -O3 -pipe" CHOST="i586-pc-linux-gnu" CLASSPATH="." CLEAN_DELAY="5" COMPILER="gcc3" CONFIG_PROTECT="/etc /usr/X11R6/lib/X11/xkb /usr/kde/2/share/config /usr/kde/3/share/config /usr/lib/mozilla/defaults/pref /usr/share/config /usr/share/texmf/dvipdfm/config/ /usr/share/texmf/dvips/config/ /usr/share/texmf/tex/generic/config/ /usr/share/texmf/tex/platex/config/ /usr/share/texmf/xdvi/ /var/qmail/control" CONFIG_PROTECT_MASK="/etc/gconf /etc/terminfo /etc/env.d" CVS_RSH="ssh" CXX="g++" CXXFLAGS="-march=pentium-mmx -O3 -pipe" DCCC_PATH="/usr/lib/distcc/bin" DISPLAY=":0.0" DISTCC_LOG="" DISTCC_VERBOSE="0" DISTDIR="/usr/portage-distfiles" EDITOR="/usr/bin/vim" FEATURES="autoaddcvs ccache sandbox" FETCHCOMMAND="/usr/bin/wget -t 5 ${URI} -P ${DISTDIR}" GDK_USE_XFT="1" GENTOO_MIRRORS=" ftp://ftp.gg3.net/pub/linux/gentoo" GLIBC_SSP_CHECKED="1" GLOBUS_LOCATION="/opt/gt3" GRP_STAGE23_USE="ipv6 pam tcpd readline nls ssl gpm perl python berkdb acl ncurses" GTK_IM_MODULE="xim" GUILE_LOAD_PATH="/usr/share/guile/1.6" G_BROKEN_FILENAMES="1" HISTCONTROL="ignoreboth" HOME="/root" HOSTNAME="lion.gg3.net" INFODIR="/usr/share/info:/usr/X11R6/info" INFOPATH="/usr/share/info:/usr/share/gcc-data/i686-pc-linux-gnu/3.3/info" INPUTRC="/etc/inputrc" JAVAC="/opt/sun-jdk-1.5.0_beta1/bin/javac" JAVA_HOME="/opt/sun-jdk-1.5.0_beta1" JDK_HOME="/opt/sun-jdk-1.5.0_beta1" KBUILD_OUTPUT_PREFIX="/var/tmp/linux-build/" LESS="-R" LESSOPEN="|/usr/bin/lesspipe.sh %s" LINGUAS="en" LINUX_PORTAGE_WRITABLE="no" LOGNAME="root" LS_COLORS="no=00:fi=00:di=01;34:ln=01;36:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=01;05;37;41:mi=01;05;37;41:ex=01;32:*.cmd=01;32:*.exe=01;32:*.com=01;32:*.btm=01;32:*.bat=01;32:*.sh=01;32:*.csh=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.gz=01;31:*.bz2=01;31:*.bz=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.mng=01;35:*.xcf=01;35:*.pcx=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.avi=01;35:*.mkv=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.mov=01;35:*.qt=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.fli=01;35:*.gl=01;35:*.dl=01;35:" MAIL="/var/spool/mail/root" MAKEOPTS="-j2" MANPATH="/usr/share/man:/usr/local/share/man:/usr/share/gcc-data/i686-pc-linux-gnu/3.3/man:/usr/X11R6/man::/opt/sun-jdk-1.5.0_beta1/man:/usr/qt/3/doc/man:/opt/mathematica-5.0/SystemFiles/SystemDocumentation/Unix/:/opt/vmware/man" MOZILLA_FIVE_HOME="/usr/lib/mozilla" NOCOLOR="false" PAGER="/usr/bin/less" PATH="/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/opt/bin:/usr/i686-pc-linux-gnu/gcc-bin/3.3:/opt/Acrobat5:/opt/stuffit/bin:/usr/X11R6/bin:/opt/sun-jdk-1.5.0_beta1/bin:/opt/sun-jdk-1.5.0_beta1/jre/bin:/opt/sun-jdk-1.5.0_beta1/jre/javaws:/usr/qt/3/bin:/opt/vmware/bin:/root/bin" PKGDIR="/usr/portage-mouse/packages" PORTAGE_BINHOST_CHUNKSIZE="3000" PORTAGE_CACHEDIR="/var/cache/edb/dep/" PORTAGE_CALLER="emerge" PORTAGE_GID="250" PORTAGE_MASTER_PID="31200" PORTAGE_TMPDIR="/var/tmp" PORTDIR="/usr/portage" PORTDIR_LOCAL="/usr/portage-mouse" PORTDIR_OVERLAY="/usr/portage-chutz" PORT_LOGDIR="/var/log/portage-mouse" PRELINK_PATH="" PRELINK_PATH_MASK="" PS1="\[\033[01;31m\]\u@\[\033[01;33m\]\h \W \$ \[\033[00m\]" PWD="/root" QMAKESPEC="linux-g++" QTDIR="/usr/qt/3" RESUMECOMMAND="/usr/bin/wget -c -t 5 ${URI} -P ${DISTDIR}" ROOT="/remote/mouse/" RPMDIR="/usr/portage-mouse/rpm" RSYNC_EXCLUDEFROM="/etc/portage/rsync_excludes" RSYNC_RETRIES="0" RSYNC_TIMEOUT="180" SANE_CONFIG_DIR="/etc/sane.d" SGML_CATALOG_FILES="/etc/sgml/sgml-docbook.cat:/etc/sgml/openjade-1.3.2.cat:/etc/sgml/sgml-ent.cat:/etc/sgml/sgml-docbook-3.0.cat:/etc/sgml/sgml-docbook-3.1.cat:/etc/sgml/sgml-docbook-4.0.cat:/etc/sgml/sgml-docbook-4.1.cat:/etc/sgml/sgml-lite.cat:/etc/sgml/dsssl-docbook-stylesheets.cat" SHELL="/bin/bash" SHLVL="1" SYNC="rsync://rsync.gg3.net/gentoo-portage" TERM="xterm" USE="X aalib acl apm avi berkdb canna cjk crypt dga esd gdbm gif gpm gtk gtk2 imap imlib ipv6 jpeg linguas_en maildir mmx mozilla moznocompose moznoirc moznomail ncurses oggvorbis oss pam pcmcia perl png pnp python readline slang ssl tcpd truetype trusted x86 xml xml2 zlib" USER="root" USERLAND="GNU" USERNAME="root" USE_EXPAND="VIDEO_CARDS INPUT_DEVICES LINGUAS" XARGS="xargs -r" XAUTHORITY="/root/.xauthTP2uJI" XIM="kinput2" XINITRC="/etc/X11/xinit/xinitrc" XMODIFIERS="@im=kinput2" _="/usr/bin/emerge"
OK, here is a much easier way to reproduce the bug: 1. Create a new ebuild in overlay; e.g, here I have $ cat /usr/portage-chutz/test-test/foo/foo-1.ebuild SRC_URI="" LICENSE="GPL-2" SLOT="0" KEYWORDS="x86" DEPEND="" #RDEPEND="" src_compile() { einfo "No compilation" } src_install() { dodir /etc date > "${D}/etc/test-config-protect" } 2. emerge foo-1.ebuild 3. edit /etc/test-config-protect and change it # Checkpoint 1 4. emerge foo-1.ebuild again 5. mkdir -p /mnt/test 6. mount --rbind / /mnt/test # this needs kernel 2.6? 7. edit /mnt/test/etc/test-config-protect # Checkpoint 2 8. ROOT=/mnt/test/ emerge foo-1.ebuild Actual results: At step 4 the file is preserved, but at step 8 it isn't. Espected results: The file is preserved at both steps 4 and 8.
Georgi, have you experienced this w/ portage-2.0.51_pre1* at all?
I haven't tried the still hardmasked 2.0.51 series. And I will not be able to try until the 22nd of September.
It'll still happen, I do believe. Portage makes the assumption that if you're installing into a new root, then you're building a system and shouldn't bother with config protection. It's not documented either way, so it's undefined behavior. The current behavior was probably hashed out to suit catalyst. Different Outlooks: "My System" aka "ROOT=/" "New System" aka "Non-/ ROOT" "Alternate Root" aka "chroot" You are in the "New System" assumption.
Just to confirm that this behavior is still in 2.0.51. I am pretty sure that there was either a bug or a discussion, but has it been considered to add this Alternate Root behavior? Was this (New Root) really intentional (to suit catalyst), because after looking at the code it does seem more like a bug. I did some very simple changes to portage.py to implement an Alternate Root outlook like this: 1. I moved the system imports to the beginning of the file. 2. I moved the os.environment.has_key["ROOT"] check after these imports 3. I added this: if os.environ.has_key("CHROOT"): CHROOT = root else: CHROOT = "/" 4. I changed some of the constants that followed to be prefixed with CHROOT+. This way the configuration files are also read from the ROOT path. 5. Up to here, I have portage read all configuration (/etc/make.conf, profile etc) from ROOT. Now for the config protection Looking at dblink.updateprotect I see this: for x in string.split(self.settings["CONFIG_PROTECT"]): ppath=normalize_path(self.myroot+x)+"/" if os.path.isdir(ppath): self.protect.append(ppath) In other words, the config protect directory list contains paths prefixed with myroot. However, in dblink.mergeme we have the following code: offset=stufftomerge mytruncpath="/"+offset+"/" myppath=self.isprotected(mytruncpath) However, stufftomerge doesn't come with a myroot prefix, and therefore myppath checks if a path WITHOUT the myroot prefix exists in the config_protect list of paths that are prefixed with myroot. I changed the invocation if isprotected to pass a parameter prefixed with self.myroot, changed all invocations of new_protect_filename to use "mydest" instead of "myrealdest", because I was getting ._cfg* files in /etc instead of $ROOT/etc and it all seemed to work just as I expected for an Alternate Root. So what do you think? I am not attaching the patch, because it was just proof of concept. I am sure a portage dev can do the job better than me. If you say it's worth it, I'll clean it up, make it backwards compatible (to actually introduce the new behavior *only* when CHROOT is set) and submit it.
As I elaborated upon at http://article.gmane.org/gmane.linux.gentoo.devel/26328 , I disagree with this assumption. People may want to maintain systems in a ROOT, not just create them.
Created attachment 53496 [details, diff] config-protect-root.patch Since the bug has woken up, here is a patch for your testing pleasure. This one will make portage use the full path (prefixed with ROOT), when merging config-protected files. I tested various combinations and it seems to work fine.
Created attachment 53497 [details] foo-1.ebuild A dummy ebuild to test the config-protect patch. Put it somewhere in your overlay: for example $PORTDIR_OVERLAY/app-text/foo. Apply the patch from attachment #53496 [details, diff] and test with: emerge foo emerge foo ROOT=/tmp/dummydir emerge foo ROOT=/tmp/dummydir emerge foo The commands will hopefully behave as expected.
As Nick said, there are two perspectives about ROOT - but let's forget those. Let's just look at documentation. CONFIG_PROTECT = [space delimited list of dirs] All directories that are defined here will have "config file protection" enabled for them. For more information, please see `emerge --help config`. ROOT = [path] Use ROOT to specify the target root filesystem to be used for merging packages or ebuilds. Typically, you should set this setting in the environment rather than in /etc/make.conf itself. It's typically used for creating new build images. Defaults to /. Nowhere does it say that CONFIG_PROTECT will magically be enhanced with ROOT's counterparts. Therefore there is no bug as far as incorrect behaviour goes. If you're talking a feature enhancement, I still say WONTFIX - or DUPLICATE of iggy's "separate config for root" bug. If CONFIG_PROTECT is automatically enhanced with ROOT's counterparts, there'll be a counterpart to this bug where somebody *didn't* want CONFIG_PROTECT for ROOT and so set it to -* and then had some required build-time packages installed to /. If you want some of your ROOT config protected, add the directories to CONFIG_PROTECT. When the alternate config bug is fixed, config protection will be part of it.
*** Bug 83289 has been marked as a duplicate of this bug. ***
A separate CONFIG_PROTECT for $ROOT will likely appear when bug #40302 is implemented.