i was testing out a package that installed a large number of files and when i went to clean it, portage was taking it's sweet time unmerging it (not its fault, it has to do checks before it can rm a file ... i just happened to know that i wanted the whole tree gone ...), so i bg-ed emerge, rm -rf the dir, and then fg-ed emerge so as to clean up the portage db ... i was able to cause these 2 errors ... test case #1 emerge app-games/noegnud-data emerge -C app-games/noegnud-data <in middle of clearing /usr/share/games/noegnud_data hit ctrl+z> rm -rf /usr/share/games/noegnud_data fg portage continued to clean files until some time later it barfed with: Traceback (most recent call last): File "/usr/bin/emerge", line 1776, in ? if 1==unmerge(myaction, myfiles): File "/usr/bin/emerge", line 1445, in unmerge retval=portage.unmerge(mysplit[0],mysplit[1],portage.root,unmerge_action not in ["clean","prune"]) File "/usr/lib/python2.2/site-packages/portage.py", line 1869, in unmerge mylink.unmerge(trimworld=mytrimworld) File "/usr/lib/python2.2/site-packages/portage.py", line 4173, in unmerge if len(objld)>0: TypeError: len() of unsized object ------------------------------------------------------------------------------------------- test case #2 emerge testing-portage-rm emerge -C testing-portage-rm <in middle of clearing /usr/share/games/noegnud_data hit ctrl+z> rm -rf /usr/share/games/noegnud_data fg second case portage exited immediatly: Traceback (most recent call last): File "/usr/bin/emerge", line 1776, in ? if 1==unmerge(myaction, myfiles): File "/usr/bin/emerge", line 1445, in unmerge retval=portage.unmerge(mysplit[0],mysplit[1],portage.root,unmerge_action not in ["clean","prune"]) File "/usr/lib/python2.2/site-packages/portage.py", line 1869, in unmerge mylink.unmerge(trimworld=mytrimworld) File "/usr/lib/python2.2/site-packages/portage.py", line 4090, in unmerge lstatobj=os.lstat(obj) OSError: [Errno 2] No such file or directory: '/test/9959' as you can see, portage was kind of pissed about the whole thing ... root@vapier 0 usr # emerge info Portage 2.0.48-r3 (default-x86-1.4, gcc-3.2.3, glibc-2.3.2-r1) ================================================================= System uname: 2.4.21 i686 Intel(R) Pentium(R) 4 CPU 1.80GHz GENTOO_MIRRORS=" http://wh0rd.ro/gentoo" CONFIG_PROTECT="/etc /var/qmail/control /usr/kde/2/share/config /usr/kde/3/share/config /usr/X11R6/lib/X11/xkb /usr/kde/3.1/share/config /usr/share/texmf/tex/generic/config/ /usr/share/texmf/tex/platex/config/ /opt/glftpd/etc /usr/share/config" CONFIG_PROTECT_MASK="/etc/gconf /etc/env.d" PORTDIR="/usr/portage" DISTDIR="/usr/portage/distfiles" PKGDIR="/root/packages" PORTAGE_TMPDIR="/var/tmp" PORTDIR_OVERLAY="/usr/local/portage" USE="x86 mad emu10k1 joystick dedicated nptl cdr scanner -3dfx -3dnow aalib -acl -afs -alsa apm -arts -atlas avi -berkdb -bonobo -canna -cjk crypt cups dga directfb -doc dvd encode esd -evo fbcon flash -freewnn -gb gd gdbm ggi -ggz gif -gnome -gnome-libs gphoto2 gpm gtk gtk2 -gtkhtml -guile -icc -icc-pgo imap imlib -innodb ipv6 java jpeg kde kerberos -lcms -ldap -libg++ -libgda libwww -matrox -maildir -mbox -mikmod mmx -motif mozilla mpeg -mule mysql nas ncurses -nls nocardbus -oci8 -odbc oggvorbis opengl -oss pam -pcmcia pda pdflib perl pic plotutils png pnp -postgres python qt qtmt quicktime readline -ruby samba sasl sdl -slang slp snmp socks5 spell sse ssl -static svga tcltk tcpd -tetex tiff truetype -trusted -voodoo3 wavelan X -xface xml xml2 xmms xv -zeo zlib" COMPILER="gcc3" CHOST="i686-pc-linux-gnu" CFLAGS="-march=pentium4 -O9 -pipe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE" CXXFLAGS="-march=pentium4 -O9 -pipe -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE" ACCEPT_KEYWORDS="x86 ~x86" MAKEOPTS="-j2" AUTOCLEAN="yes" SYNC="rsync://wh0rd.ro/gentoo-portage" FEATURES="sandbox ccache noauto"
Created attachment 14430 [details] testing-portage-rm-1.ebuild ebuild for test case #2
So you want even more checks ?
why test when you can just catch an error i thought thats why 'try: catch:' we for
Part of me says "don't do stupid crap while portage is running" and part of me says portage shouldn't crash ;) A try...catch block with a little message when the exception is caught telling the user something bad happened would be nice, I wouldn't expect portage to be able to recover from it though.
IMO it would be reasonable to catch and ignore (or log) "No such file or directory" exceptions when the file in question is being removed anyway. We would need to handle the exception(s) in dblink.unmerge() for each of pkgfiles, mysyms, and mydirs.
This is probably safe now with the stat and lstat caching in dblink.unmerge() that I've added to trunk in revision 2691 (to release in 2.1_pre5).
In revision 2695 I've added exception handling to catch the possible ENOENT error from portage_checksum.perform_md5().
Released in 2.1_pre5.